Compare commits

..
Author SHA1 Message Date
Dominik Sokal 5f73b0a2d7 v0.56.0 2022-07-28 11:43:00 +02:00
James Ide d194f18b8e Set Kirby and Will as codeowners for EAS Update CLI (#1233) 2022-07-26 09:22:45 -07:00
Wojciech Kozyra 17e1a145e8 [eas-cli] Fix newlines in cli deprecation message (#1231)
* [eas-cli] Fix newlines in cli deprecation message

* Update CHANGELOG
2022-07-26 10:46:09 +02:00
Kim Brandwijk 7ebb547fd9 [eas-cli] Invoke export with sourcemaps on update (#1228) 2022-07-22 12:47:37 +02:00
Wojciech Kozyra 6eca9ad564 [eas-cli] Add eas build:version:sync command (#1219) 2022-07-21 16:04:15 +02:00
Dominik Sokal 229f00a8ed Update CHANGELOG.md 2022-07-21 10:25:32 +02:00
Jérémy Barbet 2bbf7f2b6d chore: add better message on how to self-upgrade eas-cli (#1222)
* fix: make sure we add a line when needed while runing commands

* chore: add instruction on how to upgrade + remove ending new line

* chore: don't make the * bold
2022-07-21 10:24:10 +02:00
Dominik SokalandBrent Vatne d578abc69a [ENG-5017] display queue type when waiting (#1217)
* display queue type when waiting

* Update packages/eas-cli/src/build/build.ts

Co-authored-by: Brent Vatne <[email protected]>

* update CHANGELOG.md

Co-authored-by: Brent Vatne <[email protected]>
2022-07-20 09:36:22 +02:00
Wojciech Kozyra 89253f5767 [eas-cli] Add eas build:version:set command (#1209) 2022-07-18 13:26:46 +02:00
Kim Brandwijk dd5afd354a [cli] Change wording on build warning for bundle id/package name (#1211) 2022-07-16 20:43:36 +02:00
Dominik Sokal bdcc768354 rename uploadAsync -> uploadFileAtPathToS3Async (#1216) 2022-07-15 12:13:18 +02:00
Dominik Sokal 9cd2bafac5 fix CHANGELOG bot (#1215)
* upgrade node to 18.6.0 and yarn to 1.22.19

* upgrade dependencies
2022-07-15 12:13:09 +02:00
45 changed files with 1454 additions and 260 deletions

No files matched your search

+6
View File
@@ -8,14 +8,20 @@ This is the log of notable changes to EAS CLI and related packages.
### 🎉 New features
- Display build queue type when waiting. ([#1217](https://github.com/expo/eas-cli/pull/1217) by [@dsokal](https://github.com/dsokal))
- Add better message on how to upgrade EAS CLI. ([#1222](https://github.com/expo/eas-cli/pull/1222) by [@jeremybarbet](https://github.com/jeremybarbet), [#1231](https://github.com/expo/eas-cli/pull/1231) by [@wkozyra95](https://github.com/wkozyra95))
- Invoke export with sourcemaps on update. ([#1228](https://github.com/expo/eas-cli/pull/1228) by [@kbrandwijk](https://github.com/kbrandwijk))
### 🐛 Bug fixes
- Show spinner instead of silently timing out during asset upload. ([#1206](https://github.com/expo/eas-cli/pull/1206) by [@wschurman](https://github.com/wschurman))
- Fix build archive S3 URLs. ([#1207](https://github.com/expo/eas-cli/pull/1207) by [@dsokal](https://github.com/dsokal))
- `autoIncrement` option on iOS will update versions of all targets that depend on an application target. ([#1219](https://github.com/expo/eas-cli/pull/1219) by [@wkozyra95](https://github.com/wkozyra95))
### 🧹 Chores
- Increase max number of chained "extends" in build profiles. ([#1208](https://github.com/expo/eas-cli/pull/1208) by [@wkozyra95](https://github.com/wkozyra95))
- Change wording on build warning for bundle id/package name. ([#1211](https://github.com/expo/eas-cli/pull/1211) by [@kbrandwijk](https://github.com/kbrandwijk))
## [0.55.1](https://github.com/expo/eas-cli/releases/tag/v0.55.1) - 2022-07-12
+3
View File
@@ -6,6 +6,9 @@ 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/update @kgc00 @wschurman
packages/eas-cli/src/commands/update @kgc00 @wschurman
packages/eas-cli/schema @bycedric
packages/eas-cli/src/metadata @bycedric
packages/eas-cli/src/commands/metadata @bycedric
+1 -1
View File
@@ -1,5 +1,5 @@
{
"npmClient": "yarn",
"useWorkspaces": true,
"version": "0.55.1"
"version": "0.56.0"
}
+2 -2
View File
@@ -32,7 +32,7 @@
"typescript": "4.7.4"
},
"volta": {
"node": "18.2.0",
"yarn": "1.22.18"
"node": "18.6.0",
"yarn": "1.22.19"
}
}
+98 -100
View File
@@ -22,69 +22,68 @@ yarn global add eas-cli
# Usage
```sh
# runs the command
eas COMMAND
# prints the version
# runs the command
eas (-v|--version|version)
# outputs help for specific command
# prints the version
eas --help COMMAND
# outputs help for specific command
```
# Commands
<!-- commands -->
- [`eas account:login`](#eas-accountlogin)
- [`eas account:logout`](#eas-accountlogout)
- [`eas account:view`](#eas-accountview)
- [`eas analytics [STATUS]`](#eas-analytics-status)
- [`eas autocomplete [SHELL]`](#eas-autocomplete-shell)
- [`eas branch:create [NAME]`](#eas-branchcreate-name)
- [`eas branch:delete [NAME]`](#eas-branchdelete-name)
- [`eas branch:list`](#eas-branchlist)
- [`eas branch:rename`](#eas-branchrename)
- [`eas branch:view [NAME]`](#eas-branchview-name)
- [`eas build`](#eas-build)
- [`eas build:cancel [BUILD_ID]`](#eas-buildcancel-build_id)
- [`eas build:configure`](#eas-buildconfigure)
- [`eas build:inspect`](#eas-buildinspect)
- [`eas build:list`](#eas-buildlist)
- [`eas build:submit`](#eas-buildsubmit)
- [`eas build:view [BUILD_ID]`](#eas-buildview-build_id)
- [`eas channel:create [NAME]`](#eas-channelcreate-name)
- [`eas channel:edit [NAME]`](#eas-channeledit-name)
- [`eas channel:list`](#eas-channellist)
- [`eas channel:view [NAME]`](#eas-channelview-name)
- [`eas config`](#eas-config)
- [`eas credentials`](#eas-credentials)
- [`eas device:create`](#eas-devicecreate)
- [`eas device:delete`](#eas-devicedelete)
- [`eas device:list`](#eas-devicelist)
- [`eas device:view [UDID]`](#eas-deviceview-udid)
- [`eas diagnostics`](#eas-diagnostics)
- [`eas help [COMMAND]`](#eas-help-command)
- [`eas init`](#eas-init)
- [`eas login`](#eas-login)
- [`eas logout`](#eas-logout)
- [`eas metadata:pull`](#eas-metadatapull)
- [`eas metadata:push`](#eas-metadatapush)
- [`eas project:info`](#eas-projectinfo)
- [`eas project:init`](#eas-projectinit)
- [`eas secret:create`](#eas-secretcreate)
- [`eas secret:delete`](#eas-secretdelete)
- [`eas secret:list`](#eas-secretlist)
- [`eas submit`](#eas-submit)
- [`eas update`](#eas-update)
- [`eas update:configure`](#eas-updateconfigure)
- [`eas update:delete GROUPID`](#eas-updatedelete-groupid)
- [`eas update:list`](#eas-updatelist)
- [`eas update:view GROUPID`](#eas-updateview-groupid)
- [`eas webhook:create`](#eas-webhookcreate)
- [`eas webhook:delete [ID]`](#eas-webhookdelete-id)
- [`eas webhook:list`](#eas-webhooklist)
- [`eas webhook:update`](#eas-webhookupdate)
- [`eas webhook:view ID`](#eas-webhookview-id)
- [`eas whoami`](#eas-whoami)
* [`eas account:login`](#eas-accountlogin)
* [`eas account:logout`](#eas-accountlogout)
* [`eas account:view`](#eas-accountview)
* [`eas analytics [STATUS]`](#eas-analytics-status)
* [`eas autocomplete [SHELL]`](#eas-autocomplete-shell)
* [`eas branch:create [NAME]`](#eas-branchcreate-name)
* [`eas branch:delete [NAME]`](#eas-branchdelete-name)
* [`eas branch:list`](#eas-branchlist)
* [`eas branch:rename`](#eas-branchrename)
* [`eas branch:view [NAME]`](#eas-branchview-name)
* [`eas build`](#eas-build)
* [`eas build:cancel [BUILD_ID]`](#eas-buildcancel-build_id)
* [`eas build:configure`](#eas-buildconfigure)
* [`eas build:inspect`](#eas-buildinspect)
* [`eas build:list`](#eas-buildlist)
* [`eas build:submit`](#eas-buildsubmit)
* [`eas build:view [BUILD_ID]`](#eas-buildview-build_id)
* [`eas channel:create [NAME]`](#eas-channelcreate-name)
* [`eas channel:edit [NAME]`](#eas-channeledit-name)
* [`eas channel:list`](#eas-channellist)
* [`eas channel:view [NAME]`](#eas-channelview-name)
* [`eas config`](#eas-config)
* [`eas credentials`](#eas-credentials)
* [`eas device:create`](#eas-devicecreate)
* [`eas device:delete`](#eas-devicedelete)
* [`eas device:list`](#eas-devicelist)
* [`eas device:view [UDID]`](#eas-deviceview-udid)
* [`eas diagnostics`](#eas-diagnostics)
* [`eas help [COMMAND]`](#eas-help-command)
* [`eas init`](#eas-init)
* [`eas login`](#eas-login)
* [`eas logout`](#eas-logout)
* [`eas metadata:pull`](#eas-metadatapull)
* [`eas metadata:push`](#eas-metadatapush)
* [`eas project:info`](#eas-projectinfo)
* [`eas project:init`](#eas-projectinit)
* [`eas secret:create`](#eas-secretcreate)
* [`eas secret:delete`](#eas-secretdelete)
* [`eas secret:list`](#eas-secretlist)
* [`eas submit`](#eas-submit)
* [`eas update`](#eas-update)
* [`eas update:configure`](#eas-updateconfigure)
* [`eas update:delete GROUPID`](#eas-updatedelete-groupid)
* [`eas update:list`](#eas-updatelist)
* [`eas update:view GROUPID`](#eas-updateview-groupid)
* [`eas webhook:create`](#eas-webhookcreate)
* [`eas webhook:delete [ID]`](#eas-webhookdelete-id)
* [`eas webhook:list`](#eas-webhooklist)
* [`eas webhook:update`](#eas-webhookupdate)
* [`eas webhook:view ID`](#eas-webhookview-id)
* [`eas whoami`](#eas-whoami)
## `eas account:login`
@@ -101,7 +100,7 @@ ALIASES
$ eas login
```
_See code: [src/commands/account/login.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/account/login.ts)_
_See code: [src/commands/account/login.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/account/login.ts)_
## `eas account:logout`
@@ -118,7 +117,7 @@ ALIASES
$ eas logout
```
_See code: [src/commands/account/logout.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/account/logout.ts)_
_See code: [src/commands/account/logout.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/account/logout.ts)_
## `eas account:view`
@@ -135,7 +134,7 @@ ALIASES
$ eas whoami
```
_See code: [src/commands/account/view.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/account/view.ts)_
_See code: [src/commands/account/view.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/account/view.ts)_
## `eas analytics [STATUS]`
@@ -149,7 +148,7 @@ DESCRIPTION
display or change analytics settings
```
_See code: [src/commands/analytics.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/analytics.ts)_
_See code: [src/commands/analytics.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/analytics.ts)_
## `eas autocomplete [SHELL]`
@@ -198,7 +197,7 @@ DESCRIPTION
create a branch
```
_See code: [src/commands/branch/create.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/branch/create.ts)_
_See code: [src/commands/branch/create.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/branch/create.ts)_
## `eas branch:delete [NAME]`
@@ -218,7 +217,7 @@ DESCRIPTION
delete a branch
```
_See code: [src/commands/branch/delete.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/branch/delete.ts)_
_See code: [src/commands/branch/delete.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/branch/delete.ts)_
## `eas branch:list`
@@ -235,7 +234,7 @@ DESCRIPTION
list all branches
```
_See code: [src/commands/branch/list.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/branch/list.ts)_
_See code: [src/commands/branch/list.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/branch/list.ts)_
## `eas branch:rename`
@@ -254,7 +253,7 @@ DESCRIPTION
rename a branch
```
_See code: [src/commands/branch/rename.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/branch/rename.ts)_
_See code: [src/commands/branch/rename.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/branch/rename.ts)_
## `eas branch:view [NAME]`
@@ -274,7 +273,7 @@ DESCRIPTION
view a branch
```
_See code: [src/commands/branch/view.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/branch/view.ts)_
_See code: [src/commands/branch/view.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/branch/view.ts)_
## `eas build`
@@ -303,7 +302,7 @@ DESCRIPTION
start a build
```
_See code: [src/commands/build/index.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/build/index.ts)_
_See code: [src/commands/build/index.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/build/index.ts)_
## `eas build:cancel [BUILD_ID]`
@@ -317,7 +316,7 @@ DESCRIPTION
cancel a build
```
_See code: [src/commands/build/cancel.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/build/cancel.ts)_
_See code: [src/commands/build/cancel.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/build/cancel.ts)_
## `eas build:configure`
@@ -334,7 +333,7 @@ DESCRIPTION
configure the project to support EAS Build
```
_See code: [src/commands/build/configure.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/build/configure.ts)_
_See code: [src/commands/build/configure.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/build/configure.ts)_
## `eas build:inspect`
@@ -369,7 +368,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.55.1/packages/eas-cli/src/commands/build/inspect.ts)_
_See code: [src/commands/build/inspect.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/build/inspect.ts)_
## `eas build:list`
@@ -402,7 +401,7 @@ DESCRIPTION
list all builds for your project
```
_See code: [src/commands/build/list.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/build/list.ts)_
_See code: [src/commands/build/list.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/build/list.ts)_
## `eas build:submit`
@@ -447,7 +446,7 @@ DESCRIPTION
view a build for your project
```
_See code: [src/commands/build/view.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/build/view.ts)_
_See code: [src/commands/build/view.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/build/view.ts)_
## `eas channel:create [NAME]`
@@ -467,7 +466,7 @@ DESCRIPTION
create a channel
```
_See code: [src/commands/channel/create.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/channel/create.ts)_
_See code: [src/commands/channel/create.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/channel/create.ts)_
## `eas channel:edit [NAME]`
@@ -488,7 +487,7 @@ DESCRIPTION
point a channel at a new branch
```
_See code: [src/commands/channel/edit.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/channel/edit.ts)_
_See code: [src/commands/channel/edit.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/channel/edit.ts)_
## `eas channel:list`
@@ -505,7 +504,7 @@ DESCRIPTION
list all channels
```
_See code: [src/commands/channel/list.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/channel/list.ts)_
_See code: [src/commands/channel/list.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/channel/list.ts)_
## `eas channel:view [NAME]`
@@ -525,7 +524,7 @@ DESCRIPTION
view a channel
```
_See code: [src/commands/channel/view.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/channel/view.ts)_
_See code: [src/commands/channel/view.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/channel/view.ts)_
## `eas config`
@@ -543,7 +542,7 @@ DESCRIPTION
display project configuration (app.json + eas.json)
```
_See code: [src/commands/config.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/config.ts)_
_See code: [src/commands/config.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/config.ts)_
## `eas credentials`
@@ -557,7 +556,7 @@ DESCRIPTION
manage credentials
```
_See code: [src/commands/credentials.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/credentials.ts)_
_See code: [src/commands/credentials.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/credentials.ts)_
## `eas device:create`
@@ -571,7 +570,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.55.1/packages/eas-cli/src/commands/device/create.ts)_
_See code: [src/commands/device/create.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/device/create.ts)_
## `eas device:delete`
@@ -589,7 +588,7 @@ DESCRIPTION
remove a registered device from your account
```
_See code: [src/commands/device/delete.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/device/delete.ts)_
_See code: [src/commands/device/delete.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/device/delete.ts)_
## `eas device:list`
@@ -606,7 +605,7 @@ DESCRIPTION
list all registered devices for your account
```
_See code: [src/commands/device/list.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/device/list.ts)_
_See code: [src/commands/device/list.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/device/list.ts)_
## `eas device:view [UDID]`
@@ -620,7 +619,7 @@ DESCRIPTION
view a device for your project
```
_See code: [src/commands/device/view.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/device/view.ts)_
_See code: [src/commands/device/view.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/device/view.ts)_
## `eas diagnostics`
@@ -634,7 +633,7 @@ DESCRIPTION
display environment info
```
_See code: [src/commands/diagnostics.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/diagnostics.ts)_
_See code: [src/commands/diagnostics.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/diagnostics.ts)_
## `eas help [COMMAND]`
@@ -716,7 +715,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.55.1/packages/eas-cli/src/commands/metadata/pull.ts)_
_See code: [src/commands/metadata/pull.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/metadata/pull.ts)_
## `eas metadata:push`
@@ -733,7 +732,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.55.1/packages/eas-cli/src/commands/metadata/push.ts)_
_See code: [src/commands/metadata/push.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/metadata/push.ts)_
## `eas project:info`
@@ -747,7 +746,7 @@ DESCRIPTION
information about the current project
```
_See code: [src/commands/project/info.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/project/info.ts)_
_See code: [src/commands/project/info.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/project/info.ts)_
## `eas project:init`
@@ -764,7 +763,7 @@ ALIASES
$ eas init
```
_See code: [src/commands/project/init.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/project/init.ts)_
_See code: [src/commands/project/init.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/project/init.ts)_
## `eas secret:create`
@@ -784,7 +783,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.55.1/packages/eas-cli/src/commands/secret/create.ts)_
_See code: [src/commands/secret/create.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/secret/create.ts)_
## `eas secret:delete`
@@ -801,7 +800,7 @@ DESCRIPTION
delete an environment secret by ID
```
_See code: [src/commands/secret/delete.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/secret/delete.ts)_
_See code: [src/commands/secret/delete.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/secret/delete.ts)_
## `eas secret:list`
@@ -815,7 +814,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.55.1/packages/eas-cli/src/commands/secret/list.ts)_
_See code: [src/commands/secret/list.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/secret/list.ts)_
## `eas submit`
@@ -845,7 +844,7 @@ ALIASES
$ eas build:submit
```
_See code: [src/commands/submit.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/submit.ts)_
_See code: [src/commands/submit.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/submit.ts)_
## `eas update`
@@ -875,7 +874,7 @@ DESCRIPTION
publish an update group
```
_See code: [src/commands/update/index.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/update/index.ts)_
_See code: [src/commands/update/index.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/update/index.ts)_
## `eas update:configure`
@@ -892,7 +891,7 @@ DESCRIPTION
configure the project to support EAS Update
```
_See code: [src/commands/update/configure.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/update/configure.ts)_
_See code: [src/commands/update/configure.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/update/configure.ts)_
## `eas update:delete GROUPID`
@@ -912,7 +911,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.55.1/packages/eas-cli/src/commands/update/delete.ts)_
_See code: [src/commands/update/delete.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/update/delete.ts)_
## `eas update:list`
@@ -931,7 +930,7 @@ DESCRIPTION
view the recent updates for a branch
```
_See code: [src/commands/update/list.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/update/list.ts)_
_See code: [src/commands/update/list.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/update/list.ts)_
## `eas update:view GROUPID`
@@ -951,7 +950,7 @@ DESCRIPTION
update group details
```
_See code: [src/commands/update/view.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/update/view.ts)_
_See code: [src/commands/update/view.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/update/view.ts)_
## `eas webhook:create`
@@ -971,7 +970,7 @@ DESCRIPTION
create a webhook
```
_See code: [src/commands/webhook/create.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/webhook/create.ts)_
_See code: [src/commands/webhook/create.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/webhook/create.ts)_
## `eas webhook:delete [ID]`
@@ -988,7 +987,7 @@ DESCRIPTION
delete a webhook
```
_See code: [src/commands/webhook/delete.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/webhook/delete.ts)_
_See code: [src/commands/webhook/delete.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/webhook/delete.ts)_
## `eas webhook:list`
@@ -1005,7 +1004,7 @@ DESCRIPTION
list webhooks
```
_See code: [src/commands/webhook/list.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/webhook/list.ts)_
_See code: [src/commands/webhook/list.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/webhook/list.ts)_
## `eas webhook:update`
@@ -1026,7 +1025,7 @@ DESCRIPTION
update a webhook
```
_See code: [src/commands/webhook/update.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/webhook/update.ts)_
_See code: [src/commands/webhook/update.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/webhook/update.ts)_
## `eas webhook:view ID`
@@ -1043,7 +1042,7 @@ DESCRIPTION
view a webhook
```
_See code: [src/commands/webhook/view.ts](https://github.com/expo/eas-cli/blob/v0.55.1/packages/eas-cli/src/commands/webhook/view.ts)_
_See code: [src/commands/webhook/view.ts](https://github.com/expo/eas-cli/blob/v0.56.0/packages/eas-cli/src/commands/webhook/view.ts)_
## `eas whoami`
@@ -1059,5 +1058,4 @@ DESCRIPTION
ALIASES
$ eas whoami
```
<!-- commandsstop -->
+341 -4
View File
@@ -5870,6 +5870,51 @@
"isDeprecated": true,
"deprecationReason": "No longer supported"
},
{
"name": "latestAppVersionByPlatformAndApplicationIdentifier",
"description": null,
"args": [
{
"name": "applicationIdentifier",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"defaultValue": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "platform",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "ENUM",
"name": "AppPlatform",
"ofType": null
}
},
"defaultValue": null,
"isDeprecated": false,
"deprecationReason": null
}
],
"type": {
"kind": "OBJECT",
"name": "AppVersion",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "latestReleaseForReleaseChannel",
"description": null,
@@ -7856,6 +7901,256 @@
],
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "AppVersion",
"description": "Represents Play Store/App Store version of an application",
"fields": [
{
"name": "applicationIdentifier",
"description": "Store identifier for an application\n - Android - applicationId\n - iOS - bundle identifier",
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "buildVersion",
"description": "Value that identifies build in a store (it's visible to developers, but not to end users)\n- Android - versionCode in build.gradle (\"android.versionCode\" field in app.json)\n- iOS - CFBundleVersion in Info.plist (\"ios.buildNumber\" field in app.json)",
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "id",
"description": null,
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "platform",
"description": null,
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "ENUM",
"name": "AppPlatform",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "runtimeVersion",
"description": null,
"args": [],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "storeVersion",
"description": "User-facing version in a store\n- Android - versionName in build.gradle (\"version\" field in app.json)\n- iOS - CFBundleShortVersionString in Info.plist (\"version\" field in app.json)",
"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": "INPUT_OBJECT",
"name": "AppVersionInput",
"description": null,
"fields": null,
"inputFields": [
{
"name": "appId",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
},
"defaultValue": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "applicationIdentifier",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"defaultValue": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "buildVersion",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"defaultValue": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "platform",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "ENUM",
"name": "AppPlatform",
"ofType": null
}
},
"defaultValue": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "runtimeVersion",
"description": null,
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "storeVersion",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"defaultValue": null,
"isDeprecated": false,
"deprecationReason": null
}
],
"interfaces": null,
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "AppVersionMutation",
"description": null,
"fields": [
{
"name": "createAppVersion",
"description": "Create an app version",
"args": [
{
"name": "appVersionInput",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "INPUT_OBJECT",
"name": "AppVersionInput",
"ofType": null
}
},
"defaultValue": null,
"isDeprecated": false,
"deprecationReason": null
}
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "AppVersion",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "AppleAppIdentifier",
@@ -9540,9 +9835,13 @@
"name": "appleTeamId",
"description": null,
"type": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
},
"defaultValue": null,
"isDeprecated": false,
@@ -10209,7 +10508,7 @@
"args": [
{
"name": "assetContentTypes",
"description": "max 600",
"description": "max 1400",
"type": {
"kind": "NON_NULL",
"name": null,
@@ -10763,6 +11062,22 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "maxBuildTimeSeconds",
"description": null,
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "metrics",
"description": null,
@@ -12574,6 +12889,12 @@
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "NORMAL_PLUS",
"description": null,
"isDeprecated": false,
"deprecationReason": null
}
],
"possibleTypes": null
@@ -19950,6 +20271,22 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "appVersion",
"description": "Mutations that modify an AppVersion",
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "AppVersionMutation",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "appleAppIdentifier",
"description": "Mutations that modify an Identifier for an iOS App",
+7 -3
View File
@@ -1,7 +1,7 @@
{
"name": "eas-cli",
"description": "EAS command line tool",
"version": "0.55.1",
"version": "0.56.0",
"author": "Expo <[email protected]>",
"bin": {
"eas": "./bin/run"
@@ -14,7 +14,7 @@
"@expo/config-plugins": "4.1.4",
"@expo/config-types": "45.0.0",
"@expo/eas-build-job": "0.2.77",
"@expo/eas-json": "0.55.0",
"@expo/eas-json": "0.56.0",
"@expo/json-file": "8.2.36",
"@expo/multipart-body-parser": "1.1.0",
"@expo/pkcs12": "0.0.8",
@@ -166,7 +166,7 @@
},
"warn-if-update-available": {
"timeoutInDays": 0.5,
"message": "<%= chalk.bold('★') %> <%= chalk.bold(config.name + '@' + latest) %> <%= chalk.bold('is now available, please upgrade.') %>\n<%= chalk.dim('Proceeding with outdated version') %>\n"
"message": "<%= chalk('★') %> <%= chalk.bold(config.name + '@' + latest) %> <%= chalk.bold('is now available.') %>\n<%= chalk.dim('To upgrade, run ') %><%= chalk.dim(chalk.bold('npm install -g eas-cli')) %><%= chalk.dim('.') %>\n<%= chalk.dim('Proceeding with outdated version.') %>\n"
},
"update": {
"node": {
@@ -200,5 +200,9 @@
"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"
},
"volta": {
"node": "18.6.0",
"yarn": "1.22.19"
}
}
@@ -89,7 +89,7 @@ describe(bumpVersionAsync, () => {
expect(resolveConfigValue(buildGradle, 'versionName')).toBe('3.0.0');
});
it('bumps expo.version and gradle versionCode when strategy = BumpStrategy.SHORT_VERSION', async () => {
it('bumps expo.version and gradle versionCode when strategy = BumpStrategy.APP_VERSION', async () => {
const nativeVersionName = '1.0.0'; // this should be overwritten by bumpVersionAsync
const fakeExp = initBareWorkflowProject({ versionName: nativeVersionName });
+24 -10
View File
@@ -11,6 +11,7 @@ import {
parseGradleCommand,
resolveConfigValue,
} from '../../project/android/gradleUtils';
import { getNextVersionCode } from '../../project/android/versions';
import { resolveWorkflowAsync } from '../../project/workflow';
import { updateAppJsonConfigAsync } from '../utils/appJson';
import { bumpAppVersionAsync, ensureStaticConfigExists } from '../utils/version';
@@ -46,9 +47,10 @@ export async function bumpVersionAsync({
await bumpVersionInAppJsonAsync({ bumpStrategy, projectDir, exp });
Log.log('Updated versions in app.json');
await writeVersionsToBuildGradleAsync({
await updateNativeVersionsAsync({
projectDir,
exp,
version: exp.version,
versionCode: exp.android?.versionCode,
});
Log.log('Synchronized versions with build gradle');
}
@@ -74,7 +76,7 @@ export async function bumpVersionInAppJsonAsync({
await bumpAppVersionAsync({ appVersion, projectDir, exp });
} else {
const versionCode = AndroidConfig.Version.getVersionCode(exp);
const bumpedVersionCode = versionCode + 1;
const bumpedVersionCode = getNextVersionCode(versionCode);
Log.log(
`Bumping ${chalk.bold('expo.android.versionCode')} from ${chalk.bold(
versionCode
@@ -116,21 +118,33 @@ export async function maybeResolveVersionsAsync(
}
}
async function writeVersionsToBuildGradleAsync({
export async function updateNativeVersionsAsync({
projectDir,
exp,
version,
versionCode,
}: {
projectDir: string;
exp: ExpoConfig;
}): Promise<string> {
version?: string;
versionCode?: number;
}): Promise<void> {
const buildGradle = await readBuildGradleAsync(projectDir);
if (!buildGradle) {
throw new Error('This project is missing a build.gradle file.');
}
let updatedBuildGradle = AndroidConfig.Version.setVersionName(exp, buildGradle);
updatedBuildGradle = AndroidConfig.Version.setVersionCode(exp, updatedBuildGradle);
let updatedBuildGradle = buildGradle;
if (version !== undefined) {
updatedBuildGradle = updatedBuildGradle.replace(
new RegExp(`versionName ".*"`),
`versionName "${version}"`
);
}
if (versionCode !== undefined) {
updatedBuildGradle = updatedBuildGradle.replace(
new RegExp(`versionCode.*`),
`versionCode ${versionCode}`
);
}
await writeBuildGradleAsync({ projectDir, buildGradle: updatedBuildGradle });
return updatedBuildGradle;
}
async function readBuildGradleAsync(projectDir: string): Promise<string | undefined> {
+9 -3
View File
@@ -25,7 +25,7 @@ import {
appPlatformEmojis,
requestedPlatformDisplayNames,
} from '../platform';
import { uploadAsync } from '../uploads';
import { uploadFileAtPathToS3Async } from '../uploads';
import { formatBytes } from '../utils/files';
import { createProgressTracker } from '../utils/progress';
import { sleepAsync } from '../utils/promise';
@@ -179,7 +179,7 @@ async function uploadProjectAsync<TPlatform extends Platform>(
const projectTarball = await makeProjectTarballAsync();
projectTarballPath = projectTarball.path;
const { bucketKey } = await uploadAsync(
const { bucketKey } = await uploadFileAtPathToS3Async(
UploadSessionType.EasBuildProjectSources,
projectTarball.path,
createProgressTracker({
@@ -352,7 +352,7 @@ async function handleSingleBuildProgressAsync(
);
}
Log.newLine();
Log.log('Waiting in queue');
Log.log(`Waiting in ${priorityToQueueDisplayName[build.priority]}`);
queueProgressBar.start(
build.initialQueuePosition + 1,
build.initialQueuePosition - build.queuePosition + 1,
@@ -385,6 +385,12 @@ async function handleSingleBuildProgressAsync(
return { refetch: true };
}
const priorityToQueueDisplayName: Record<BuildPriority, string> = {
[BuildPriority.Normal]: 'queue',
[BuildPriority.NormalPlus]: 'queue',
[BuildPriority.High]: 'priority queue',
};
const statusToDisplayName: Record<BuildStatus, string> = {
[BuildStatus.New]: 'waiting to enter the queue (concurrency limit reached)',
[BuildStatus.InQueue]: 'in queue',
+2 -3
View File
@@ -1,7 +1,6 @@
import { ExpoConfig } from '@expo/config';
import { Platform, Workflow } from '@expo/eas-build-job';
import { BuildProfile } from '@expo/eas-json';
import type { XCBuildConfiguration } from 'xcode';
import { BuildProfile, EasJson } from '@expo/eas-json';
import { TrackingContext } from '../analytics/common';
import { CredentialsContext } from '../credentials/context';
@@ -21,7 +20,6 @@ export interface AndroidBuildContext {
export interface IosBuildContext {
bundleIdentifier: string;
applicationTargetBuildSettings: XCBuildConfiguration['buildSettings'];
applicationTarget: Target;
targets: Target[];
xcodeBuildContext: XcodeBuildContext;
@@ -29,6 +27,7 @@ export interface IosBuildContext {
export interface BuildContext<T extends Platform> {
accountName: string;
easJsonCliConfig: EasJson['cli'];
buildProfile: BuildProfile<T>;
buildProfileName: string;
resourceClass: BuildResourceClass;
+4 -1
View File
@@ -1,5 +1,5 @@
import { Platform } from '@expo/eas-build-job';
import { BuildProfile } from '@expo/eas-json';
import { BuildProfile, EasJson } from '@expo/eas-json';
import JsonFile from '@expo/json-file';
import resolveFrom from 'resolve-from';
import { v4 as uuidv4 } from 'uuid';
@@ -21,6 +21,7 @@ import { LocalBuildOptions } from './local';
export async function createBuildContextAsync<T extends Platform>({
buildProfileName,
buildProfile,
easJsonCliConfig,
clearCache = false,
localBuildOptions,
nonInteractive = false,
@@ -30,6 +31,7 @@ export async function createBuildContextAsync<T extends Platform>({
}: {
buildProfileName: string;
buildProfile: BuildProfile<T>;
easJsonCliConfig: EasJson['cli'];
clearCache: boolean;
localBuildOptions: LocalBuildOptions;
nonInteractive: boolean;
@@ -74,6 +76,7 @@ export async function createBuildContextAsync<T extends Platform>({
buildProfile,
buildProfileName,
resourceClass,
easJsonCliConfig,
clearCache,
credentialsCtx,
exp,
@@ -3,6 +3,7 @@ import { IOSConfig } from '@expo/config-plugins';
import fs from 'fs-extra';
import { vol } from 'memfs';
import os from 'os';
import type { XCBuildConfiguration } from 'xcode';
import { readPlistAsync } from '../../../utils/plist';
import {
@@ -17,6 +18,12 @@ import {
jest.mock('fs');
const getXCBuildConfigurationFromPbxproj = jest.spyOn(
IOSConfig.Target,
'getXCBuildConfigurationFromPbxproj'
);
const getPbxproj = jest.spyOn(IOSConfig.XcodeUtils, 'getPbxproj');
afterAll(async () => {
// do not remove the following line
// this fixes a weird error with tempy in @expo/image-utils
@@ -51,14 +58,34 @@ describe(evaluateTemplateString, () => {
// bare workflow
describe(bumpVersionAsync, () => {
beforeEach(() => {
getPbxproj.mockImplementation(() => ({} as any));
});
afterEach(() => {
getXCBuildConfigurationFromPbxproj.mockReset();
getPbxproj.mockReset();
});
it('bumps expo.ios.buildNumber and CFBundleVersion when strategy = BumpStrategy.BUILD_NUMBER', async () => {
const fakeExp = initBareWorkflowProject();
getXCBuildConfigurationFromPbxproj.mockImplementation(
() =>
({
buildSettings: {
INFOPLIST_FILE: 'myproject/Info.plist',
},
} as XCBuildConfiguration)
);
await bumpVersionAsync({
bumpStrategy: BumpStrategy.BUILD_NUMBER,
projectDir: '/repo',
exp: fakeExp,
buildSettings: {},
targets: [
{
targetName: 'example',
bundleIdentifier: 'example.com',
entitlements: {},
},
],
});
const appJSON = await fs.readJSON('/repo/app.json');
@@ -76,13 +103,25 @@ describe(bumpVersionAsync, () => {
it('bumps expo.ios.buildNumber and CFBundleVersion for non default Info.plist location', async () => {
const fakeExp = initBareWorkflowProject({ infoPlistName: 'Info2.plist' });
getXCBuildConfigurationFromPbxproj.mockImplementation(
() =>
({
buildSettings: {
INFOPLIST_FILE: '$(SRCROOT)/myproject/Info2.plist',
},
} as XCBuildConfiguration)
);
await bumpVersionAsync({
bumpStrategy: BumpStrategy.BUILD_NUMBER,
projectDir: '/repo',
exp: fakeExp,
buildSettings: {
INFOPLIST_FILE: '$(SRCROOT)/myproject/Info2.plist',
},
targets: [
{
targetName: 'example',
bundleIdentifier: 'example.com',
entitlements: {},
},
],
});
const appJSON = await fs.readJSON('/repo/app.json');
@@ -97,14 +136,27 @@ describe(bumpVersionAsync, () => {
expect(infoPlist['CFBundleVersion']).toBe('2');
});
it('bumps expo.version and CFBundleShortVersionString when strategy = BumpStrategy.SHORT_VERSION', async () => {
it('bumps expo.version and CFBundleShortVersionString when strategy = BumpStrategy.APP_VERSION', async () => {
const fakeExp = initBareWorkflowProject();
getXCBuildConfigurationFromPbxproj.mockImplementation(
() =>
({
buildSettings: {
INFOPLIST_FILE: 'myproject/Info.plist',
},
} as XCBuildConfiguration)
);
await bumpVersionAsync({
bumpStrategy: BumpStrategy.APP_VERSION,
projectDir: '/repo',
exp: fakeExp,
buildSettings: {},
targets: [
{
targetName: 'example',
bundleIdentifier: 'example.com',
entitlements: {},
},
],
});
const appJSON = await fs.readJSON('/repo/app.json');
@@ -121,12 +173,25 @@ describe(bumpVersionAsync, () => {
it('does not bump any version when strategy = BumpStrategy.NOOP', async () => {
const fakeExp = initBareWorkflowProject();
getXCBuildConfigurationFromPbxproj.mockImplementation(
() =>
({
buildSettings: {
INFOPLIST_FILE: 'myproject/Info.plist',
},
} as XCBuildConfiguration)
);
await bumpVersionAsync({
bumpStrategy: BumpStrategy.NOOP,
projectDir: '/repo',
exp: fakeExp,
buildSettings: {},
targets: [
{
targetName: 'example',
bundleIdentifier: 'example.com',
entitlements: {},
},
],
});
const appJSON = await fs.readJSON('/repo/app.json');
@@ -288,9 +353,9 @@ describe(getInfoPlistPath, () => {
function initBareWorkflowProject({
appVersion = '1.0.0',
version = '1',
buildNumber = '1',
infoPlistName = 'Info.plist',
}: { appVersion?: string; version?: string; infoPlistName?: string } = {}): ExpoConfig {
}: { appVersion?: string; buildNumber?: string; infoPlistName?: string } = {}): ExpoConfig {
const fakeExp: ExpoConfig = {
name: 'myproject',
slug: 'myproject',
@@ -311,7 +376,7 @@ function initBareWorkflowProject({
<key>CFBundleShortVersionString</key>
<string>${appVersion}</string>
<key>CFBundleVersion</key>
<string>${version}</string>
<string>${buildNumber}</string>
</dict>
</plist>`,
},
+2 -21
View File
@@ -1,8 +1,6 @@
import { IOSConfig } from '@expo/config-plugins';
import { Ios, Job, Metadata, Platform, Workflow } from '@expo/eas-build-job';
import type { XCBuildConfiguration } from 'xcode';
import { IosCredentials, Target } from '../../credentials/ios/types';
import { IosCredentials } from '../../credentials/ios/types';
import { BuildParamsInput } from '../../graphql/generated';
import { BuildMutation, BuildResult } from '../../graphql/mutations/BuildMutation';
import { ensureBundleIdentifierIsDefinedForManagedProjectAsync } from '../../project/ios/bundleIdentifier';
@@ -44,12 +42,10 @@ export async function createIosContextAsync(
env: buildProfile.env,
});
const applicationTarget = findApplicationTarget(targets);
const applicationTargetBuildSettings = resolveBuildSettings(ctx, applicationTarget);
return {
bundleIdentifier: applicationTarget.bundleIdentifier,
applicationTarget,
applicationTargetBuildSettings,
targets,
xcodeBuildContext,
};
@@ -68,7 +64,7 @@ export async function prepareIosBuildAsync(
projectDir: ctx.projectDir,
exp: ctx.exp,
buildProfile: ctx.buildProfile,
buildSettings: ctx.ios.applicationTargetBuildSettings,
targets: ctx.ios.targets,
});
},
prepareJobAsync: async (
@@ -97,18 +93,3 @@ export async function prepareIosBuildAsync(
},
});
}
function resolveBuildSettings(
ctx: CommonContext<Platform.IOS>,
applicationTarget: Target
): XCBuildConfiguration['buildSettings'] {
if (ctx.workflow === Workflow.MANAGED) {
return {};
}
const project = IOSConfig.XcodeUtils.getPbxproj(ctx.projectDir);
const xcBuildConfiguration = IOSConfig.Target.getXCBuildConfigurationFromPbxproj(project, {
targetName: applicationTarget.targetName,
buildConfiguration: applicationTarget.buildConfiguration,
});
return xcBuildConfiguration?.buildSettings ?? {};
}
@@ -1,8 +1,8 @@
import { ExpoConfig } from '@expo/config';
import { Platform, Workflow } from '@expo/eas-build-job';
import { BuildProfile, IosVersionAutoIncrement } from '@expo/eas-json';
import type { XCBuildConfiguration } from 'xcode';
import { Target } from '../../credentials/ios/types';
import { isExpoUpdatesInstalled } from '../../project/projectUtils';
import { resolveWorkflowAsync } from '../../project/workflow';
import { syncUpdatesConfigurationAsync } from '../../update/ios/UpdatesModule';
@@ -12,12 +12,12 @@ export async function syncProjectConfigurationAsync({
projectDir,
exp,
buildProfile,
buildSettings,
targets,
}: {
projectDir: string;
exp: ExpoConfig;
buildProfile: BuildProfile<Platform.IOS>;
buildSettings: XCBuildConfiguration['buildSettings'];
targets: Target[];
}): Promise<void> {
const workflow = await resolveWorkflowAsync(projectDir, Platform.IOS);
const { autoIncrement } = buildProfile;
@@ -27,7 +27,7 @@ export async function syncProjectConfigurationAsync({
if (isExpoUpdatesInstalled(projectDir)) {
await syncUpdatesConfigurationAsync(projectDir, exp);
}
await bumpVersionAsync({ projectDir, exp, bumpStrategy: versionBumpStrategy, buildSettings });
await bumpVersionAsync({ projectDir, exp, bumpStrategy: versionBumpStrategy, targets });
} else {
await bumpVersionInAppJsonAsync({ projectDir, exp, bumpStrategy: versionBumpStrategy });
}
+71 -42
View File
@@ -1,16 +1,20 @@
import { ExpoConfig, getConfigFilePaths } from '@expo/config';
import { ExpoConfig } from '@expo/config';
import { IOSConfig } from '@expo/config-plugins';
import { Platform, Workflow } from '@expo/eas-build-job';
import chalk from 'chalk';
import path from 'path';
import type { XCBuildConfiguration } from 'xcode';
import { Target } from '../../credentials/ios/types';
import Log from '../../log';
import { findApplicationTarget } from '../../project/ios/target';
import { getNextBuildNumber, isValidBuildNumber } from '../../project/ios/versions';
import { resolveWorkflowAsync } from '../../project/workflow';
import { promptAsync } from '../../prompts';
import uniqBy from '../../utils/expodash/uniqBy';
import { readPlistAsync, writePlistAsync } from '../../utils/plist';
import { updateAppJsonConfigAsync } from '../utils/appJson';
import { bumpAppVersionAsync } from '../utils/version';
import { bumpAppVersionAsync, ensureStaticConfigExists } from '../utils/version';
export enum BumpStrategy {
APP_VERSION,
@@ -22,21 +26,25 @@ export async function bumpVersionAsync({
bumpStrategy,
projectDir,
exp,
buildSettings,
targets,
}: {
projectDir: string;
exp: ExpoConfig;
bumpStrategy: BumpStrategy;
buildSettings: XCBuildConfiguration['buildSettings'];
targets: Target[];
}): Promise<void> {
if (bumpStrategy === BumpStrategy.NOOP) {
return;
}
ensureStaticConfigExists(projectDir);
const infoPlist = await readInfoPlistAsync(projectDir, buildSettings);
await bumpVersionInAppJsonAsync({ bumpStrategy, projectDir, exp });
Log.log('Updated versions in app.json');
await writeVersionsToInfoPlistAsync({ projectDir, exp, infoPlist, buildSettings });
await updateNativeVersionsAsync({
projectDir,
version: exp.version,
buildNumber: exp.ios?.buildNumber,
targets,
});
Log.log('Synchronized versions with Info.plist');
}
@@ -59,10 +67,8 @@ export async function bumpVersionInAppJsonAsync({
await bumpAppVersionAsync({ appVersion, projectDir, exp });
} else {
const buildNumber = IOSConfig.Version.getBuildNumber(exp);
if (buildNumber.match(/^\d+(\.\d+)*$/)) {
const comps = buildNumber.split('.');
comps[comps.length - 1] = String(Number(comps[comps.length - 1]) + 1);
const bumpedBuildNumber = comps.join('.');
if (isValidBuildNumber(buildNumber)) {
const bumpedBuildNumber = getNextBuildNumber(buildNumber);
Log.log(
`Bumping ${chalk.bold('expo.ios.buildNumber')} from ${chalk.bold(
buildNumber
@@ -121,12 +127,21 @@ export async function readBuildNumberAsync(
export async function maybeResolveVersionsAsync(
projectDir: string,
exp: ExpoConfig,
buildSettings: XCBuildConfiguration['buildSettings']
targets: Target[]
): Promise<{ appVersion?: string; appBuildVersion?: string }> {
const applicationTarget = findApplicationTarget(targets);
try {
return {
appBuildVersion: await readBuildNumberAsync(projectDir, exp, buildSettings),
appVersion: await readShortVersionAsync(projectDir, exp, buildSettings),
appBuildVersion: await readBuildNumberAsync(
projectDir,
exp,
applicationTarget.buildSettings ?? {}
),
appVersion: await readShortVersionAsync(
projectDir,
exp,
applicationTarget.buildSettings ?? {}
),
};
} catch (err: any) {
Log.warn('Failed to read app versions.');
@@ -137,23 +152,6 @@ export async function maybeResolveVersionsAsync(
}
}
async function writeVersionsToInfoPlistAsync({
projectDir,
exp,
infoPlist,
buildSettings,
}: {
projectDir: string;
exp: ExpoConfig;
infoPlist: IOSConfig.InfoPlist;
buildSettings: XCBuildConfiguration['buildSettings'];
}): Promise<IOSConfig.InfoPlist> {
let updatedInfoPlist = IOSConfig.Version.setVersion(exp, infoPlist);
updatedInfoPlist = IOSConfig.Version.setBuildNumber(exp, updatedInfoPlist);
await writeInfoPlistAsync({ projectDir, infoPlist: updatedInfoPlist, buildSettings });
return updatedInfoPlist;
}
export function getInfoPlistPath(
projectDir: string,
buildSettings: XCBuildConfiguration['buildSettings']
@@ -181,24 +179,55 @@ async function readInfoPlistAsync(
return ((await readPlistAsync(infoPlistPath)) ?? {}) as IOSConfig.InfoPlist;
}
async function writeInfoPlistAsync({
export async function updateNativeVersionsAsync({
projectDir,
infoPlist,
buildSettings,
version,
buildNumber,
targets,
}: {
projectDir: string;
infoPlist: IOSConfig.InfoPlist;
buildSettings: XCBuildConfiguration['buildSettings'];
version?: string;
buildNumber?: string;
targets: Target[];
}): Promise<void> {
const infoPlistPath = getInfoPlistPath(projectDir, buildSettings);
await writePlistAsync(infoPlistPath, infoPlist);
const project = IOSConfig.XcodeUtils.getPbxproj(projectDir);
const iosDir = path.join(projectDir, 'ios');
const infoPlistFiles: string[] = [];
for (const target of targets) {
const { targetName, buildConfiguration } = target;
const xcBuildConfiguration = IOSConfig.Target.getXCBuildConfigurationFromPbxproj(project, {
targetName,
buildConfiguration,
});
const infoPlist = xcBuildConfiguration?.buildSettings?.INFOPLIST_FILE;
if (infoPlist) {
const evaluatedInfoPlistPath = trimQuotes(
evaluateTemplateString(infoPlist, {
SRCROOT: iosDir,
})
);
const absolutePath = path.isAbsolute(evaluatedInfoPlistPath)
? evaluatedInfoPlistPath
: path.join(iosDir, evaluatedInfoPlistPath);
infoPlistFiles.push(path.normalize(absolutePath));
}
}
const uniqueInfoPlistPaths = uniqBy(infoPlistFiles, i => i);
for (const infoPlistPath of uniqueInfoPlistPaths) {
const infoPlist = (await readPlistAsync(infoPlistPath)) as IOSConfig.InfoPlist;
if (buildNumber) {
infoPlist.CFBundleVersion = buildNumber;
}
if (version) {
infoPlist.CFBundleShortVersionString = version;
}
await writePlistAsync(infoPlistPath, infoPlist);
}
}
function ensureStaticConfigExists(projectDir: string): void {
const paths = getConfigFilePaths(projectDir);
if (!paths.staticConfigPath) {
throw new Error('autoIncrement option is not supported when using app.config.js');
}
function trimQuotes(s: string): string {
return s?.startsWith('"') && s.endsWith('"') ? s.slice(1, -1) : s;
}
export function evaluateTemplateString(
+1 -5
View File
@@ -60,11 +60,7 @@ async function maybeResolveVersionsAsync<T extends Platform>(
): Promise<{ appBuildVersion?: string; appVersion?: string }> {
if (ctx.platform === Platform.IOS) {
const iosContext = ctx as BuildContext<Platform.IOS>;
return await maybeResolveIosVersionsAsync(
ctx.projectDir,
ctx.exp,
iosContext.ios.applicationTargetBuildSettings
);
return await maybeResolveIosVersionsAsync(ctx.projectDir, ctx.exp, iosContext.ios.targets);
} else if (ctx.platform === Platform.ANDROID) {
const androidCtx = ctx as BuildContext<Platform.ANDROID>;
return await maybeResolveAndroidVersionsAsync(ctx.projectDir, ctx.exp, androidCtx.buildProfile);
@@ -1,5 +1,5 @@
import { Platform, Workflow } from '@expo/eas-build-job';
import { BuildProfile, EasJsonReader, SubmitProfile } from '@expo/eas-json';
import { BuildProfile, EasJson, EasJsonReader, SubmitProfile } from '@expo/eas-json';
import chalk from 'chalk';
import nullthrows from 'nullthrows';
@@ -80,6 +80,7 @@ export async function runBuildAndSubmitAsync(projectDir: string, flags: BuildFla
nonInteractive: flags.nonInteractive,
});
const easJsonReader = new EasJsonReader(projectDir);
const easJsonCliConfig: EasJson['cli'] = (await easJsonReader.getCliConfigAsync()) ?? {};
const platforms = toPlatforms(flags.requestedPlatform);
const buildProfiles = await getProfilesAsync({
@@ -111,6 +112,7 @@ export async function runBuildAndSubmitAsync(projectDir: string, flags: BuildFla
platformToGraphQLResourceClassMapping[buildProfile.platform][
flags.userInputResourceClass ?? UserInputResourceClass.DEFAULT
],
easJsonCliConfig,
});
if (maybeBuild) {
startedBuilds.push({ build: maybeBuild, buildProfile });
@@ -188,12 +190,14 @@ async function prepareAndStartBuildAsync({
moreBuilds,
buildProfile,
resourceClass,
easJsonCliConfig,
}: {
projectDir: string;
flags: BuildFlags;
moreBuilds: boolean;
buildProfile: ProfileData<'build'>;
resourceClass: BuildResourceClass;
easJsonCliConfig: EasJson['cli'];
}): Promise<{ build: BuildFragment | undefined; buildCtx: BuildContext<Platform> }> {
const buildCtx = await createBuildContextAsync({
buildProfileName: buildProfile.profileName,
@@ -204,6 +208,7 @@ async function prepareAndStartBuildAsync({
platform: buildProfile.platform,
projectDir,
localBuildOptions: flags.localBuildOptions,
easJsonCliConfig,
});
if (moreBuilds) {
@@ -0,0 +1,114 @@
import { getRuntimeVersionNullable } from '@expo/config-plugins/build/utils/Updates';
import { Platform } from '@expo/eas-build-job';
import { EasJsonReader } from '@expo/eas-json';
import { Flags } from '@oclif/core';
import chalk from 'chalk';
import EasCommand from '../../../commandUtils/EasCommand';
import { AppVersionMutation } from '../../../graphql/mutations/AppVersionMutation';
import { AppVersionQuery } from '../../../graphql/queries/AppVersionQuery';
import { toAppPlatform } from '../../../graphql/types/AppPlatform';
import Log from '../../../log';
import { selectPlatformAsync } from '../../../platform';
import { VERSION_CODE_REQUIREMENTS, isValidVersionCode } from '../../../project/android/versions';
import { getApplicationIdentifierAsync } from '../../../project/applicationIdentifier';
import { getExpoConfig } from '../../../project/expoConfig';
import { BUILD_NUMBER_REQUIREMENTS, isValidBuildNumber } from '../../../project/ios/versions';
import {
findProjectRootAsync,
getProjectFullNameAsync,
getProjectIdAsync,
} from '../../../project/projectUtils';
import {
ensureRemoteVersionPolicyAsync,
getBuildVersionName,
validateAppConfigForRemoteVersionPolicyAsync,
} from '../../../project/remoteVersionSource';
import { promptAsync } from '../../../prompts';
export default class BuildVersionSetView extends EasCommand {
static description = 'Update version of an app.';
static hidden = true;
static flags = {
platform: Flags.enum({
char: 'p',
options: ['android', 'ios'],
}),
profile: Flags.string({
description:
'Name of the build profile from eas.json. Defaults to "production" if defined in eas.json.',
helpValue: 'PROFILE_NAME',
}),
};
public async runAsync(): Promise<void> {
const { flags } = await this.parse(BuildVersionSetView);
const projectDir = await findProjectRootAsync();
const platform = await selectPlatformAsync(flags.platform);
const easJsonReader = new EasJsonReader(projectDir);
await ensureRemoteVersionPolicyAsync(projectDir, easJsonReader);
const profile = await easJsonReader.getBuildProfileAsync(platform, flags.profile ?? undefined);
const exp = getExpoConfig(projectDir, { env: profile.env });
const projectId = await getProjectIdAsync(exp);
const projectFullName = await getProjectFullNameAsync(exp);
await validateAppConfigForRemoteVersionPolicyAsync(exp);
const applicationIdentifier = await getApplicationIdentifierAsync(
projectDir,
exp,
profile,
platform
);
const remoteVersions = await AppVersionQuery.latestVersionAsync(
projectId,
toAppPlatform(platform),
applicationIdentifier
);
const currentStateMessage = remoteVersions?.buildVersion
? `Project ${chalk.bold(projectFullName)} with ${getApplicationIdentifierName(
platform
)} "${applicationIdentifier}" is configured with ${getBuildVersionName(platform)} ${
remoteVersions.buildVersion
}.`
: `Project ${chalk.bold(projectFullName)} with ${getApplicationIdentifierName(
platform
)} "${applicationIdentifier}" does not have any ${getBuildVersionName(
platform
)} configured.`;
const versionPromptMessage = remoteVersions?.buildVersion
? `What version would you like to set?`
: `What version would you like to initialize it with?`;
Log.log(currentStateMessage);
const { version } = await promptAsync({
type: platform === Platform.ANDROID ? 'number' : 'text',
name: 'version',
message: versionPromptMessage,
validate:
platform === Platform.ANDROID
? value => isValidVersionCode(value) || `Invalid value: ${VERSION_CODE_REQUIREMENTS}.`
: value => isValidBuildNumber(value) || `Invalid value: ${BUILD_NUMBER_REQUIREMENTS}.`,
});
await AppVersionMutation.createAppVersionAsync({
appId: projectId,
platform: toAppPlatform(platform),
applicationIdentifier,
storeVersion: exp.version ?? '1.0.0',
buildVersion: String(version),
runtimeVersion: getRuntimeVersionNullable(exp, platform) ?? undefined,
});
}
}
function getApplicationIdentifierName(platform: Platform): string {
if (platform === Platform.ANDROID) {
return 'application ID';
} else {
return 'bundle identifier';
}
}
@@ -0,0 +1,184 @@
import { ExpoConfig } from '@expo/config';
import { Platform, Workflow } from '@expo/eas-build-job';
import { BuildProfile, EasJsonReader } from '@expo/eas-json';
import { Flags } from '@oclif/core';
import chalk from 'chalk';
import { updateNativeVersionsAsync as updateAndroidNativeVersionsAsync } from '../../../build/android/version';
import { updateNativeVersionsAsync as updateIosNativeVersionsAsync } from '../../../build/ios/version';
import EasCommand from '../../../commandUtils/EasCommand';
import { AppVersionQuery } from '../../../graphql/queries/AppVersionQuery';
import { toAppPlatform } from '../../../graphql/types/AppPlatform';
import Log from '../../../log';
import {
appPlatformDisplayNames,
selectRequestedPlatformAsync,
toPlatforms,
} from '../../../platform';
import { getAppBuildGradleAsync } from '../../../project/android/gradleUtils';
import { VERSION_CODE_REQUIREMENTS, isValidVersionCode } from '../../../project/android/versions';
import { getApplicationIdentifierAsync } from '../../../project/applicationIdentifier';
import { getExpoConfig } from '../../../project/expoConfig';
import { resolveXcodeBuildContextAsync } from '../../../project/ios/scheme';
import { resolveTargetsAsync } from '../../../project/ios/target';
import { BUILD_NUMBER_REQUIREMENTS, isValidBuildNumber } from '../../../project/ios/versions';
import { findProjectRootAsync, getProjectIdAsync } from '../../../project/projectUtils';
import {
ensureRemoteVersionPolicyAsync,
getBuildVersionName,
validateAppConfigForRemoteVersionPolicyAsync,
} from '../../../project/remoteVersionSource';
import { resolveWorkflowAsync } from '../../../project/workflow';
import { getProfilesAsync } from '../../../utils/profiles';
interface SyncContext<T extends Platform> {
projectDir: string;
exp: ExpoConfig;
workflow: Workflow;
profile: BuildProfile<T>;
buildVersion: string;
}
export default class BuildVersionSyncView extends EasCommand {
public static description = 'Update a version in native code with a value stored on EAS servers';
static hidden = true;
public static flags = {
platform: Flags.enum({
char: 'p',
options: ['android', 'ios', 'all'],
}),
profile: Flags.string({
description:
'Name of the build profile from eas.json. Defaults to "production" if defined in eas.json.',
helpValue: 'PROFILE_NAME',
}),
};
public async runAsync(): Promise<void> {
const { flags } = await this.parse(BuildVersionSyncView);
const projectDir = await findProjectRootAsync();
const requestedPlatform = await selectRequestedPlatformAsync(flags.platform);
const easJsonReader = new EasJsonReader(projectDir);
await ensureRemoteVersionPolicyAsync(projectDir, easJsonReader);
const platforms = toPlatforms(requestedPlatform);
const buildProfiles = await getProfilesAsync({
type: 'build',
easJsonReader,
platforms,
profileName: flags.profile ?? undefined,
});
for (const profileInfo of buildProfiles) {
const exp = getExpoConfig(projectDir, { env: profileInfo.profile.env });
const projectId = await getProjectIdAsync(exp);
await validateAppConfigForRemoteVersionPolicyAsync(exp);
const platformDisplayName = appPlatformDisplayNames[toAppPlatform(profileInfo.platform)];
const applicationIdentifier = await getApplicationIdentifierAsync(
projectDir,
exp,
profileInfo.profile,
profileInfo.platform
);
const remoteVersions = await AppVersionQuery.latestVersionAsync(
projectId,
toAppPlatform(profileInfo.platform),
applicationIdentifier
);
const workflow = await resolveWorkflowAsync(projectDir, profileInfo.platform);
if (!remoteVersions?.buildVersion) {
Log.warn(
`Skipping versions sync for ${platformDisplayName}. There are no versions configured on Expo servers, use "eas build:version:set" or run a build to initialize it.`
);
continue;
}
if (workflow === Workflow.MANAGED) {
Log.warn(
`The remote value for the ${platformDisplayName} ${getBuildVersionName(
profileInfo.platform
)} is ${chalk.bold(
remoteVersions?.buildVersion
)}, but it was not synced to the local project. This command has no effect on projects using managed workflow.`
);
continue;
}
if (profileInfo.platform === Platform.ANDROID) {
this.syncAndroidAsync({
projectDir,
exp,
profile: profileInfo.profile as BuildProfile<Platform.ANDROID>,
workflow,
buildVersion: remoteVersions.buildVersion,
});
} else {
this.syncIosAsync({
projectDir,
exp,
profile: profileInfo.profile as BuildProfile<Platform.IOS>,
workflow,
buildVersion: remoteVersions.buildVersion,
});
}
Log.withTick(
`Successfully updated the ${platformDisplayName} ${getBuildVersionName(
profileInfo.platform
)} in native code to ${chalk.bold(remoteVersions?.buildVersion)}.`
);
}
}
private async syncIosAsync({
workflow,
projectDir,
exp,
profile,
buildVersion,
}: SyncContext<Platform.IOS>): Promise<void> {
const xcodeBuildContext = await resolveXcodeBuildContextAsync(
{ exp, projectDir, nonInteractive: false },
profile
);
const targets = await resolveTargetsAsync({
projectDir,
exp,
xcodeBuildContext,
env: profile.env,
});
if (!isValidBuildNumber(buildVersion)) {
throw new Error(`Invalid buildNumber (${buildVersion}), ${BUILD_NUMBER_REQUIREMENTS}.`);
}
if (workflow === Workflow.GENERIC) {
await updateIosNativeVersionsAsync({
projectDir,
buildNumber: buildVersion,
targets,
});
}
}
private async syncAndroidAsync({
projectDir,
workflow,
buildVersion,
}: SyncContext<Platform.ANDROID>): Promise<void> {
if (!isValidVersionCode(buildVersion)) {
throw new Error(`Invalid versionCode (${buildVersion}), ${VERSION_CODE_REQUIREMENTS}.`);
}
if (workflow === Workflow.GENERIC) {
const buildGradle = await getAppBuildGradleAsync(projectDir);
const isMultiFlavor =
buildGradle.android?.productFlavors || buildGradle.android?.flavorDimensions;
if (isMultiFlavor) {
throw new Error(
"Versions in native code can't be automatically synced in multi-flavor Android projects. If you are using EAS Build with app version source set to remote, the correct values will be injected at the build time."
);
}
await updateAndroidNativeVersionsAsync({ projectDir, versionCode: Number(buildVersion) });
}
}
}
@@ -1,4 +1,5 @@
import { JSONObject } from '@expo/json-file';
import type { XCBuildConfiguration } from 'xcode';
import {
CommonIosAppCredentialsFragment,
@@ -17,6 +18,7 @@ export interface Target {
bundleIdentifier: string;
parentBundleIdentifier?: string;
entitlements: JSONObject;
buildSettings?: XCBuildConfiguration['buildSettings'];
}
export interface TargetCredentials {
+76 -2
View File
@@ -834,6 +834,7 @@ export type App = Project & {
isLikedByMe: Scalars['Boolean'];
/** @deprecated No longer supported */
lastPublishedTime: Scalars['DateTime'];
latestAppVersionByPlatformAndApplicationIdentifier?: Maybe<AppVersion>;
latestReleaseForReleaseChannel?: Maybe<AppRelease>;
/** ID of latest classic update release */
latestReleaseId: Scalars['ID'];
@@ -956,6 +957,13 @@ export type AppIosAppCredentialsArgs = {
};
/** Represents an Exponent App (or Experience in legacy terms) */
export type AppLatestAppVersionByPlatformAndApplicationIdentifierArgs = {
applicationIdentifier: Scalars['String'];
platform: AppPlatform;
};
/** Represents an Exponent App (or Experience in legacy terms) */
export type AppLatestReleaseForReleaseChannelArgs = {
platform: AppPlatform;
@@ -1198,6 +1206,52 @@ export enum AppStoreConnectUserRole {
Unknown = 'UNKNOWN'
}
/** Represents Play Store/App Store version of an application */
export type AppVersion = {
__typename?: 'AppVersion';
/**
* Store identifier for an application
* - Android - applicationId
* - iOS - bundle identifier
*/
applicationIdentifier: Scalars['String'];
/**
* Value that identifies build in a store (it's visible to developers, but not to end users)
* - Android - versionCode in build.gradle ("android.versionCode" field in app.json)
* - iOS - CFBundleVersion in Info.plist ("ios.buildNumber" field in app.json)
*/
buildVersion: Scalars['String'];
id: Scalars['ID'];
platform: AppPlatform;
runtimeVersion?: Maybe<Scalars['String']>;
/**
* User-facing version in a store
* - Android - versionName in build.gradle ("version" field in app.json)
* - iOS - CFBundleShortVersionString in Info.plist ("version" field in app.json)
*/
storeVersion: Scalars['String'];
};
export type AppVersionInput = {
appId: Scalars['ID'];
applicationIdentifier: Scalars['String'];
buildVersion: Scalars['String'];
platform: AppPlatform;
runtimeVersion?: InputMaybe<Scalars['String']>;
storeVersion: Scalars['String'];
};
export type AppVersionMutation = {
__typename?: 'AppVersionMutation';
/** Create an app version */
createAppVersion: AppVersion;
};
export type AppVersionMutationCreateAppVersionArgs = {
appVersionInput: AppVersionInput;
};
export type AppleAppIdentifier = {
__typename?: 'AppleAppIdentifier';
account: Account;
@@ -1414,7 +1468,7 @@ export type ApplePushKey = {
};
export type ApplePushKeyInput = {
appleTeamId?: InputMaybe<Scalars['ID']>;
appleTeamId: Scalars['ID'];
keyIdentifier: Scalars['String'];
keyP8: Scalars['String'];
};
@@ -1584,6 +1638,7 @@ export type Build = ActivityTimelineProjectActivity & BuildOrBuildJob & {
iosEnterpriseProvisioning?: Maybe<BuildIosEnterpriseProvisioning>;
isGitWorkingTreeDirty?: Maybe<Scalars['Boolean']>;
logFiles: Array<Scalars['String']>;
maxBuildTimeSeconds: Scalars['Int'];
metrics?: Maybe<BuildMetrics>;
parentBuild?: Maybe<Build>;
platform: AppPlatform;
@@ -1817,7 +1872,8 @@ export type BuildParamsInput = {
export enum BuildPriority {
High = 'HIGH',
Normal = 'NORMAL'
Normal = 'NORMAL',
NormalPlus = 'NORMAL_PLUS'
}
/** Publicly visible data for a Build. */
@@ -2910,6 +2966,8 @@ export type RootMutation = {
app?: Maybe<AppMutation>;
/** Mutations that modify an App Store Connect Api Key */
appStoreConnectApiKey: AppStoreConnectApiKeyMutation;
/** Mutations that modify an AppVersion */
appVersion: AppVersionMutation;
/** Mutations that modify an Identifier for an iOS App */
appleAppIdentifier: AppleAppIdentifierMutation;
/** Mutations that modify an Apple Device */
@@ -4330,6 +4388,13 @@ export type CreateAppMutationVariables = Exact<{
export type CreateAppMutation = { __typename?: 'RootMutation', app?: { __typename?: 'AppMutation', createApp: { __typename?: 'App', id: string } } | null };
export type CreateAppVersionMutationVariables = Exact<{
appVersionInput: AppVersionInput;
}>;
export type CreateAppVersionMutation = { __typename?: 'RootMutation', appVersion: { __typename?: 'AppVersionMutation', createAppVersion: { __typename?: 'AppVersion', id: string } } };
export type CreateAndroidBuildMutationVariables = Exact<{
appId: Scalars['ID'];
job: AndroidJobInput;
@@ -4448,6 +4513,15 @@ export type DeleteWebhookMutationVariables = Exact<{
export type DeleteWebhookMutation = { __typename?: 'RootMutation', webhook: { __typename?: 'WebhookMutation', deleteWebhook: { __typename?: 'DeleteWebhookResult', id: string } } };
export type LatestAppVersionQueryVariables = Exact<{
appId: Scalars['String'];
platform: AppPlatform;
applicationIdentifier: Scalars['String'];
}>;
export type LatestAppVersionQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, latestAppVersionByPlatformAndApplicationIdentifier?: { __typename?: 'AppVersion', id: string, storeVersion: string, buildVersion: string } | null } } };
export type ViewBranchQueryVariables = Exact<{
appId: Scalars['String'];
name: Scalars['String'];
@@ -0,0 +1,42 @@
import assert from 'assert';
import gql from 'graphql-tag';
import { graphqlClient, withErrorHandlingAsync } from '../client';
import {
AppPlatform,
CreateAppVersionMutation,
CreateAppVersionMutationVariables,
} from '../generated';
export const AppVersionMutation = {
async createAppVersionAsync(appVersionInput: {
appId: string;
platform: AppPlatform;
applicationIdentifier: string;
storeVersion: string;
buildVersion: string;
runtimeVersion?: string;
}): Promise<string> {
const data = await withErrorHandlingAsync(
graphqlClient
.mutation<CreateAppVersionMutation, CreateAppVersionMutationVariables>(
gql`
mutation CreateAppVersionMutation($appVersionInput: AppVersionInput!) {
appVersion {
createAppVersion(appVersionInput: $appVersionInput) {
id
}
}
}
`,
{
appVersionInput,
}
)
.toPromise()
);
const appVersionId = data.appVersion?.createAppVersion.id;
assert(appVersionId, 'AppVersion ID must be defined');
return appVersionId;
},
};
@@ -0,0 +1,51 @@
import gql from 'graphql-tag';
import { graphqlClient, withErrorHandlingAsync } from '../client';
import {
AppPlatform,
AppVersion,
LatestAppVersionQuery,
LatestAppVersionQueryVariables,
} from '../generated';
export const AppVersionQuery = {
async latestVersionAsync(
appId: string,
platform: AppPlatform,
applicationIdentifier: string
): Promise<Pick<AppVersion, 'storeVersion' | 'buildVersion'> | null> {
const data = await withErrorHandlingAsync(
graphqlClient
.query<LatestAppVersionQuery, LatestAppVersionQueryVariables>(
gql`
query LatestAppVersion(
$appId: String!
$platform: AppPlatform!
$applicationIdentifier: String!
) {
app {
byId(appId: $appId) {
id
latestAppVersionByPlatformAndApplicationIdentifier(
platform: $platform
applicationIdentifier: $applicationIdentifier
) {
id
storeVersion
buildVersion
}
}
}
}
`,
{ appId, applicationIdentifier, platform },
{
additionalTypenames: ['App', 'AppVersion'],
}
)
.toPromise()
);
return data.app.byId.latestAppVersionByPlatformAndApplicationIdentifier ?? null;
},
};
+17
View File
@@ -47,6 +47,23 @@ export async function selectRequestedPlatformAsync(platform?: string): Promise<R
return requestedPlatform;
}
export async function selectPlatformAsync(platform?: string): Promise<Platform> {
if (platform && Object.values(Platform).includes(platform.toLowerCase() as Platform)) {
return platform.toLowerCase() as Platform;
}
const { resolvedPlatform } = await promptAsync({
type: 'select',
message: 'Select platform',
name: 'resolvedPlatform',
choices: [
{ title: 'Android', value: Platform.ANDROID },
{ title: 'iOS', value: Platform.IOS },
],
});
return resolvedPlatform;
}
export function toPlatforms(requestedPlatform: RequestedPlatform): Platform[] {
if (requestedPlatform === RequestedPlatform.All) {
return [Platform.ANDROID, Platform.IOS];
@@ -0,0 +1,27 @@
import { getNextVersionCode, isValidVersionCode } from '../versions';
describe(isValidVersionCode, () => {
test('isValidVersionCode()', () => {
expect(isValidVersionCode(123)).toBe(true);
expect(isValidVersionCode(12.3)).toBe(false);
expect(isValidVersionCode(-123)).toBe(false);
expect(isValidVersionCode(2000000000)).toBe(true);
expect(isValidVersionCode(2000000001)).toBe(false);
expect(isValidVersionCode('123')).toBe(true);
expect(isValidVersionCode('12.3')).toBe(false);
expect(isValidVersionCode('-123')).toBe(false);
expect(isValidVersionCode('2000000000')).toBe(true);
expect(isValidVersionCode('2000000001')).toBe(false);
});
});
describe(getNextVersionCode, () => {
test('getNextVersionCode()', () => {
expect(getNextVersionCode(123)).toBe(124);
expect(() => getNextVersionCode(12.3)).toThrowError();
expect(getNextVersionCode(1999999999)).toBe(2000000000);
expect(() => getNextVersionCode(2000000000)).toThrowError();
expect(getNextVersionCode('123')).toBe(124);
expect(() => getNextVersionCode('12.3')).toThrowError();
});
});
@@ -159,10 +159,10 @@ export function warnIfAndroidPackageDefinedInAppConfigForBareWorkflowProject(
): void {
if (AndroidConfig.Package.getPackage(exp) && !warnPrinted) {
Log.warn(
`Specifying "android.package" in ${getProjectConfigDescription(
`Specified value for "android.package" in ${getProjectConfigDescription(
projectDir
)} is deprecated for bare workflow projects.\n` +
'EAS Build depends only on the value in the native code. Please remove the deprecated configuration.'
)} is ignored because an ${chalk.bold('android')} directory was detected in the project.\n` +
'EAS Build will use the value found in the native code.'
);
warnPrinted = true;
}
@@ -0,0 +1,22 @@
import assert from 'assert';
const MAX_VERSION_CODE = 2000000000;
export const VERSION_CODE_REQUIREMENTS = `versionCode needs to be a positive integer smaller or equal to ${MAX_VERSION_CODE}`;
export function isValidVersionCode(versionCode: string | number): boolean {
const numericVersionCode = typeof versionCode === 'string' ? Number(versionCode) : versionCode;
return (
Number.isInteger(numericVersionCode) &&
numericVersionCode <= MAX_VERSION_CODE &&
numericVersionCode > 0
);
}
export function getNextVersionCode(versionCode: string | number): number {
assert(isValidVersionCode(versionCode), `Invalid versionCode ${versionCode}`);
const numericVersionCode = typeof versionCode === 'string' ? Number(versionCode) : versionCode;
if (numericVersionCode >= MAX_VERSION_CODE) {
throw new Error(`Invalid value: ${VERSION_CODE_REQUIREMENTS}.`);
}
return numericVersionCode + 1;
}
@@ -0,0 +1,49 @@
import { ExpoConfig } from '@expo/config';
import { Platform, Workflow } from '@expo/eas-build-job';
import { BuildProfile } from '@expo/eas-json';
import {
ensureApplicationIdIsDefinedForManagedProjectAsync,
getApplicationIdAsync,
} from './android/applicationId';
import { resolveGradleBuildContextAsync } from './android/gradle';
import { getBundleIdentifierAsync } from './ios/bundleIdentifier';
import { resolveXcodeBuildContextAsync } from './ios/scheme';
import { findApplicationTarget, resolveTargetsAsync } from './ios/target';
import { resolveWorkflowAsync } from './workflow';
export async function getApplicationIdentifierAsync(
projectDir: string,
exp: ExpoConfig,
buildProfile: BuildProfile,
platform: Platform
): Promise<string> {
if (platform === Platform.ANDROID) {
const profile = buildProfile as BuildProfile<Platform.ANDROID>;
const workflow = await resolveWorkflowAsync(projectDir, Platform.ANDROID);
const gradleContext = await resolveGradleBuildContextAsync(projectDir, profile);
if (workflow === Workflow.MANAGED) {
await ensureApplicationIdIsDefinedForManagedProjectAsync(projectDir, exp);
}
return await getApplicationIdAsync(projectDir, exp, gradleContext);
} else {
const profile = buildProfile as BuildProfile<Platform.IOS>;
const xcodeBuildContext = await resolveXcodeBuildContextAsync(
{ exp, projectDir, nonInteractive: false },
profile
);
const targets = await resolveTargetsAsync({
projectDir,
exp,
xcodeBuildContext,
env: profile.env,
});
const applicationTarget = findApplicationTarget(targets);
return await getBundleIdentifierAsync(projectDir, exp, {
targetName: applicationTarget.targetName,
buildConfiguration: applicationTarget.buildConfiguration,
});
}
}
@@ -41,8 +41,8 @@ export async function ensureProjectExistsAsync(projectInfo: ProjectInfo): Promis
});
const spinner = ora(`Linking to project ${chalk.bold(projectFullName)}`).start();
const maybeId = await findProjectIdByAccountNameAndSlugNullableAsync(accountName, projectName);
if (maybeId) {
spinner.succeed(`Linked to project ${chalk.bold(projectLink)}`);
projectCache[projectFullName] = maybeId;
@@ -0,0 +1,21 @@
import { getNextBuildNumber, isValidBuildNumber } from '../versions';
describe(isValidBuildNumber, () => {
test('isValidBuildNumber()', () => {
expect(isValidBuildNumber('1.2.3')).toBe(true);
expect(isValidBuildNumber('1.2')).toBe(true);
expect(isValidBuildNumber('1')).toBe(true);
expect(isValidBuildNumber('1.2.3.4')).toBe(false);
expect(isValidBuildNumber('1.2.-3')).toBe(false);
expect(isValidBuildNumber('1.a.3')).toBe(false);
});
});
describe(getNextBuildNumber, () => {
test('getNextBuildNumber', () => {
expect(getNextBuildNumber('1.2.3')).toBe('1.2.4');
expect(getNextBuildNumber('1.2')).toBe('1.3');
expect(getNextBuildNumber('1')).toBe('2');
expect(() => getNextBuildNumber('1.2.3.4')).toThrowError();
});
});
@@ -152,10 +152,10 @@ export function warnIfBundleIdentifierDefinedInAppConfigForBareWorkflowProject(
): void {
if (IOSConfig.BundleIdentifier.getBundleIdentifier(exp) && !warnPrinted) {
Log.warn(
`Specifying "ios.bundleIdentifier" in ${getProjectConfigDescription(
`Specified value for "ios.bundleIdentifier" in ${getProjectConfigDescription(
projectDir
)} is deprecated for bare workflow projects.\n` +
'EAS Build depends only on the value in the native code. Please remove the deprecated configuration.'
)} is ignored because an ${chalk.bold('ios')} directory was detected in the project.\n` +
'EAS Build will use the value found in the native code.'
);
warnPrinted = true;
}
+29 -1
View File
@@ -1,8 +1,9 @@
import { ExpoConfig } from '@expo/config';
import { IOSConfig } from '@expo/config-plugins';
import { IOSConfig, XcodeProject } from '@expo/config-plugins';
import { Platform, Workflow } from '@expo/eas-build-job';
import { JSONObject } from '@expo/json-file';
import Joi from 'joi';
import type { XCBuildConfiguration } from 'xcode';
import { Target } from '../../credentials/ios/types';
import { resolveWorkflowAsync } from '../workflow';
@@ -91,6 +92,7 @@ export async function resolveBareProjectTargetsAsync({
const { buildScheme, buildConfiguration } = xcodeBuildContext;
const result: Target[] = [];
const pbxProject = IOSConfig.XcodeUtils.getPbxproj(projectDir);
const applicationTarget = await IOSConfig.Target.findApplicationTargetWithDependenciesAsync(
projectDir,
buildScheme
@@ -108,6 +110,11 @@ export async function resolveBareProjectTargetsAsync({
bundleIdentifier,
buildConfiguration,
entitlements: entitlements ?? {},
buildSettings: resolveBareProjectBuildSettings(
pbxProject,
applicationTarget.name,
buildConfiguration
),
});
const dependencies = await resolveBareProjectDependenciesAsync({
@@ -116,6 +123,7 @@ export async function resolveBareProjectTargetsAsync({
buildConfiguration,
target: applicationTarget,
bundleIdentifier,
pbxProject,
});
if (dependencies.length > 0) {
result.push(...dependencies);
@@ -141,12 +149,14 @@ async function resolveBareProjectDependenciesAsync({
buildConfiguration,
target,
bundleIdentifier,
pbxProject,
}: {
exp: ExpoConfig;
projectDir: string;
buildConfiguration?: string;
target: IOSConfig.Target.Target;
bundleIdentifier: string;
pbxProject: XcodeProject;
}): Promise<Target[]> {
const result: Target[] = [];
@@ -166,6 +176,11 @@ async function resolveBareProjectDependenciesAsync({
bundleIdentifier: dependencyBundleIdentifier,
parentBundleIdentifier: bundleIdentifier,
entitlements: entitlements ?? {},
buildSettings: resolveBareProjectBuildSettings(
pbxProject,
dependency.name,
buildConfiguration
),
});
const dependencyDependencies = await resolveBareProjectDependenciesAsync({
exp,
@@ -173,6 +188,7 @@ async function resolveBareProjectDependenciesAsync({
buildConfiguration,
target: dependency,
bundleIdentifier: dependencyBundleIdentifier,
pbxProject,
});
if (dependencyDependencies.length > 0) {
result.push(...dependencyDependencies);
@@ -198,3 +214,15 @@ export function findTargetByName(targets: Target[], name: string): Target {
}
return target;
}
function resolveBareProjectBuildSettings(
project: XcodeProject,
targetName: string,
buildConfiguration?: string
): XCBuildConfiguration['buildSettings'] {
const xcBuildConfiguration = IOSConfig.Target.getXCBuildConfigurationFromPbxproj(project, {
targetName,
buildConfiguration,
});
return xcBuildConfiguration?.buildSettings ?? {};
}
@@ -0,0 +1,14 @@
import assert from 'assert';
export const BUILD_NUMBER_REQUIREMENTS = `buildNumber needs to consist only of up to 3 dot-separated positive integers`;
export function isValidBuildNumber(buildNumber: string): boolean {
return !!buildNumber.match(/^\d+(\.\d+)?(\.\d+)?$/);
}
export function getNextBuildNumber(buildNumber: string): string {
assert(isValidBuildNumber(buildNumber), `Invalid buildNumber ${buildNumber}`);
const comps = buildNumber.split('.');
comps[comps.length - 1] = String(Number(comps[comps.length - 1]) + 1);
return comps.join('.');
}
+1
View File
@@ -161,6 +161,7 @@ export async function buildBundlesAsync({
inputDir,
'--experimental-bundle',
'--non-interactive',
'--dump-sourcemap',
]);
}
@@ -0,0 +1,71 @@
import { ExpoConfig } from '@expo/config';
import { Platform } from '@expo/eas-build-job';
import { AppVersionSource, EasJsonReader } from '@expo/eas-json';
import chalk from 'chalk';
import fs from 'fs-extra';
import Log from '../log';
import { confirmAsync } from '../prompts';
export async function ensureRemoteVersionPolicyAsync(
projectDir: string,
easJsonReader: EasJsonReader
): Promise<void> {
const easJsonCliConfig = await easJsonReader.getCliConfigAsync();
if (easJsonCliConfig?.appVersionSource === AppVersionSource.REMOTE) {
return;
}
Log.log(
`The app version source defines whether the app version is stored locally in your project source (e.g. in app.json, Info.plist, or build.gradle) or remotely on EAS servers and only applied to the project at build time. To use this command, you will need to enable the remote version policy by adding ${chalk.bold(
'{"cli": { "appVersionSource": "remote" }}'
)} in eas.json.`
);
// TODO: add link to docs
const confirm = await confirmAsync({
message: 'Do you want to set app version source to remote now?',
});
if (!confirm) {
throw new Error('Aborting...');
}
const easJsonPath = EasJsonReader.formatEasJsonPath(projectDir);
const easJson = await fs.readJSON(easJsonPath);
easJson.cli = { ...easJson?.cli, appVersionSource: AppVersionSource.REMOTE };
await fs.writeFile(easJsonPath, `${JSON.stringify(easJson, null, 2)}\n`);
Log.withTick('Updated eas.json');
}
export async function validateAppConfigForRemoteVersionPolicyAsync(exp: ExpoConfig): Promise<void> {
if (typeof exp.runtimeVersion === 'object' && exp.runtimeVersion?.policy === 'nativeVersion') {
throw new Error(
`${chalk.bold('nativeVersion')} policy for ${chalk.bold(
'runtimeVersion'
)} is currently not supported when version source is set to remote. Switch policy e.g. to ${chalk.bold(
'appVersion'
)} or define version explicitly.`
);
}
if (exp.ios?.buildNumber !== undefined) {
throw new Error(
`${chalk.bold(
'ios.buildNumber'
)} field in app config is not supported when version source is set to remote, remove it and re-run the command.`
);
}
if (exp.android?.versionCode !== undefined) {
throw new Error(
`${chalk.bold(
'android.versionCode'
)} field in app config is not supported when version source is set to remote, remove it and re-run the command.`
);
}
}
export function getBuildVersionName(platform: Platform): string {
if (platform === Platform.ANDROID) {
return 'versionCode';
} else {
return 'buildNumber';
}
}
@@ -7,7 +7,7 @@ import { AppPlatform, BuildFragment, UploadSessionType } from '../../graphql/gen
import { BuildQuery } from '../../graphql/queries/BuildQuery';
import { toAppPlatform } from '../../graphql/types/AppPlatform';
import { confirmAsync, promptAsync } from '../../prompts';
import { uploadAsync } from '../../uploads';
import { uploadFileAtPathToS3Async } from '../../uploads';
import {
Archive,
ArchiveSourceType,
@@ -243,7 +243,9 @@ describe(getArchiveAsync, () => {
const path = '/archive.apk';
await fs.writeFile(path, 'some content');
jest.mocked(uploadAsync).mockResolvedValueOnce({ url: ARCHIVE_URL, bucketKey: 'wat' });
jest
.mocked(uploadFileAtPathToS3Async)
.mockResolvedValueOnce({ url: ARCHIVE_URL, bucketKey: 'wat' });
const archive = await getArchiveAsync({
...SOURCE_STUB_INPUT,
@@ -251,7 +253,7 @@ describe(getArchiveAsync, () => {
path,
});
expect(uploadAsync).toBeCalledWith(
expect(uploadFileAtPathToS3Async).toBeCalledWith(
UploadSessionType.EasSubmitAppArchive,
path,
expect.anything()
+2 -2
View File
@@ -1,7 +1,7 @@
import fs from 'fs-extra';
import { UploadSessionType } from '../../graphql/generated';
import { uploadAsync } from '../../uploads';
import { uploadFileAtPathToS3Async } from '../../uploads';
import { createProgressTracker } from '../../utils/progress';
export async function isExistingFileAsync(filePath: string): Promise<boolean> {
@@ -15,7 +15,7 @@ export async function isExistingFileAsync(filePath: string): Promise<boolean> {
export async function uploadAppArchiveAsync(path: string): Promise<string> {
const fileSize = (await fs.stat(path)).size;
const { url } = await uploadAsync(
const { url } = await uploadFileAtPathToS3Async(
UploadSessionType.EasSubmitAppArchive,
path,
createProgressTracker({
+1 -1
View File
@@ -10,7 +10,7 @@ import { UploadSessionType } from './graphql/generated';
import { PresignedPost, UploadSessionMutation } from './graphql/mutations/UploadSessionMutation';
import { ProgressHandler } from './utils/progress';
export async function uploadAsync(
export async function uploadFileAtPathToS3Async(
type: UploadSessionType,
path: string,
handleProgressEvent: ProgressHandler
+5 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@expo/eas-json",
"description": "A library for interacting with eas.json",
"version": "0.55.0",
"version": "0.56.0",
"author": "Expo <[email protected]>",
"bugs": "https://github.com/expo/eas-cli/issues",
"dependencies": {
@@ -38,5 +38,9 @@
},
"publishConfig": {
"access": "public"
},
"volta": {
"node": "18.6.0",
"yarn": "1.22.19"
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
export { AndroidReleaseStatus, AndroidReleaseTrack, SubmitProfile } from './submit/types';
export { getDefaultProfile as getDefaultSubmitProfile } from './submit/resolver';
export { EasJson, ProfileType } from './types';
export { EasJson, ProfileType, AppVersionSource } from './types';
export {
AndroidVersionAutoIncrement,
BuildProfile,
+2
View File
@@ -2,11 +2,13 @@ import Joi from 'joi';
import { BuildProfileSchema } from './build/schema';
import { SubmitProfileSchema } from './submit/schema';
import { AppVersionSource } from './types';
export const EasJsonSchema = Joi.object({
cli: Joi.object({
version: Joi.string(),
requireCommit: Joi.boolean(),
appVersionSource: Joi.string().valid(...Object.values(AppVersionSource)),
}),
build: Joi.object().pattern(Joi.string(), BuildProfileSchema),
submit: Joi.object().pattern(Joi.string(), SubmitProfileSchema),
+6
View File
@@ -11,10 +11,16 @@ export enum CredentialsSource {
REMOTE = 'remote',
}
export enum AppVersionSource {
LOCAL = 'local',
REMOTE = 'remote',
}
export interface EasJson {
cli?: {
version?: string;
requireCommit?: boolean;
appVersionSource?: AppVersionSource;
};
build?: { [profileName: string]: EasJsonBuildProfile };
submit?: { [profileName: string]: EasJsonSubmitProfile };
+7 -3
View File
@@ -26,9 +26,13 @@
"@types/dateformat": "3.0.1",
"@types/fs-extra": "9.0.13",
"@types/lodash-es": "4.17.6",
"@types/node": "17.0.32",
"@types/semver": "7.3.9",
"ts-node": "10.7.0",
"@types/node": "18.0.4",
"@types/semver": "7.3.10",
"ts-node": "10.9.1",
"typescript": "4.7.4"
},
"volta": {
"node": "18.6.0",
"yarn": "1.22.19"
}
}
+38 -25
View File
@@ -2,17 +2,30 @@
# yarn lockfile v1
"@cspotcode/source-map-consumer@0.8.0":
version "0.8.0"
resolved "https://registry.yarnpkg.com/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz#33bf4b7b39c178821606f669bbc447a6a629786b"
integrity sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==
"@cspotcode/[email protected]":
version "0.7.0"
resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz#4789840aa859e46d2f3173727ab707c66bf344f5"
integrity sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==
"@cspotcode/source-map-support@^0.8.0":
version "0.8.1"
resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1"
integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==
dependencies:
"@cspotcode/source-map-consumer" "0.8.0"
"@jridgewell/trace-mapping" "0.3.9"
"@jridgewell/resolve-uri@^3.0.3":
version "3.1.0"
resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78"
integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==
"@jridgewell/sourcemap-codec@^1.4.10":
version "1.4.14"
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24"
integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==
"@jridgewell/[email protected]":
version "0.3.9"
resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9"
integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==
dependencies:
"@jridgewell/resolve-uri" "^3.0.3"
"@jridgewell/sourcemap-codec" "^1.4.10"
"@tsconfig/node10@^1.0.7":
version "1.0.8"
@@ -63,15 +76,15 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.10.3.tgz#7a8f2838603ea314d1d22bb3171d899e15c57bd5"
integrity sha512-ho3Ruq+fFnBrZhUYI46n/bV2GjwzSkwuT4dTf0GkuNFmnb8nq4ny2z9JEVemFi6bdEJanHLlYfy9c6FN9B9McQ==
"@types/node@17.0.32":
version "17.0.32"
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.32.tgz#51d59d7a90ef2d0ae961791e0900cad2393a0149"
integrity sha512-eAIcfAvhf/BkHcf4pkLJ7ECpBAhh9kcxRBpip9cTiO+hf+aJrsxYxBeS6OXvOd9WqNAJmavXVpZvY1rBjNsXmw==
"@types/node@18.0.4":
version "18.0.4"
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.0.4.tgz#48aedbf35efb3af1248e4cd4d792c730290cd5d6"
integrity sha512-M0+G6V0Y4YV8cqzHssZpaNCqvYwlCiulmm0PwpNLF55r/+cT8Ol42CHRU1SEaYFH2rTwiiE1aYg/2g2rrtGdPA==
"@types/[email protected].9":
version "7.3.9"
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.9.tgz#152c6c20a7688c30b967ec1841d31ace569863fc"
integrity sha512-L/TMpyURfBkf+o/526Zb6kd/tchUP3iBDEPjqjb+U2MAJhVRxxrmr2fwpe08E7QsV7YLcpq0tUaQ9O9x97ZIxQ==
"@types/[email protected].10":
version "7.3.10"
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.10.tgz#5f19ee40cbeff87d916eedc8c2bfe2305d957f73"
integrity sha512-zsv3fsC7S84NN6nPK06u79oWgrPVd0NvOyqgghV1haPaFcVxIrP4DLomRwGAXk0ui4HZA7mOcSFL98sMVW9viw==
acorn-walk@^8.1.1:
version "8.2.0"
@@ -155,12 +168,12 @@ [email protected]:
dependencies:
lru-cache "^6.0.0"
ts-node@10.7.0:
version "10.7.0"
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.7.0.tgz#35d503d0fab3e2baa672a0e94f4b40653c2463f5"
integrity sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==
ts-node@10.9.1:
version "10.9.1"
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b"
integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==
dependencies:
"@cspotcode/source-map-support" "0.7.0"
"@cspotcode/source-map-support" "^0.8.0"
"@tsconfig/node10" "^1.0.7"
"@tsconfig/node12" "^1.0.7"
"@tsconfig/node14" "^1.0.0"
@@ -171,7 +184,7 @@ [email protected]:
create-require "^1.1.0"
diff "^4.0.1"
make-error "^1.1.1"
v8-compile-cache-lib "^3.0.0"
v8-compile-cache-lib "^3.0.1"
yn "3.1.1"
[email protected]:
@@ -189,7 +202,7 @@ universalify@^2.0.0:
resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717"
integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==
v8-compile-cache-lib@^3.0.0:
v8-compile-cache-lib@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"
integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==