Compare commits

..
1 Commits
Author SHA1 Message Date
Douglas Lowder 8186a27aa2 v16.17.2 2025-07-23 15:06:56 -07:00
95 changed files with 1080 additions and 3393 deletions

No files matched your search

+1 -7
View File
@@ -3,7 +3,7 @@ commentConfiguration:
epilogue: 'Generated by [CodeMention](https://github.com/expo/expo/actions/workflows/codemention.yaml)'
rules:
- patterns: ['**/*']
mentions: ['douglowder']
mentions: ['sjchmiela']
- patterns: ['packages/eas-cli/src/update/**']
mentions: ['wschurman', 'quinlanj']
- patterns: ['packages/eas-cli/src/commands/update/**']
@@ -22,9 +22,3 @@ rules:
mentions: ['kitten', 'kadikraman']
- patterns: ['packages/eas-cli/src/commands/deploy/**']
mentions: ['kitten', 'kadikraman']
- patterns: ['packages/eas-cli/src/commands/build/**']
mentions: ['sjchmiela']
- patterns: ['packages/eas-cli/src/build/**']
mentions: ['sjchmiela']
- patterns: ['packages/eas-cli/src/commands/workflow/**']
mentions: ['sjchmiela']
+7 -7
View File
@@ -18,7 +18,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: ${{ github.ref }}
release_name: 'eas-cli@${{ env.EAS_CLI_VERSION }}'
draft: true
build-linux:
name: Build for Linux
@@ -28,7 +28,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 22
node-version: 20
- run: yarn install --frozen-lockfile --check-files
- run: yarn build
- name: Ensure GraphQL schema and generated code is up-to-date
@@ -73,7 +73,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 22
node-version: 20
- run: brew install python-setuptools
env:
HOMEBREW_NO_AUTO_UPDATE: 1
@@ -116,7 +116,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 22
node-version: 20
- run: yarn install --frozen-lockfile --check-files
- run: sudo apt-get install nsis
- run: yarn build
@@ -158,7 +158,7 @@ jobs:
with:
registry-url: 'https://registry.npmjs.org/'
scope: 'expo'
node-version: 22
node-version: 20
- name: Install dependencies
run: yarn install --frozen-lockfile --check-files
- name: Build
@@ -191,7 +191,7 @@ jobs:
token: ${{ secrets.EXPO_BOT_PAT }}
- uses: actions/setup-node@v2
with:
node-version: 22
node-version: 20
- name: Install dependencies
working-directory: ./scripts
run: yarn install --frozen-lockfile --check-files
@@ -211,7 +211,7 @@ jobs:
git config --global user.email "[email protected]"
git config --global user.name "Expo CI"
git add CHANGELOG.md
git commit --allow-empty -m "update CHANGELOG.md"
git commit -m "update CHANGELOG.md"
git push
- name: Prepare changelog for Slack
run: |
+3
View File
@@ -5,6 +5,9 @@ on:
branches: [main]
pull_request:
branches: [main]
paths:
- .github/workflows/test-graphql.yml
- packages/eas-cli/src/**
schedule:
- cron: '0 8 * * *' # 8:00 AM UTC time every day
-48
View File
@@ -1,48 +0,0 @@
on:
workflow_dispatch:
inputs:
version:
type: string
required: false
description: 'Version number for the release'
dry_run:
type: boolean
required: true
default: true
description: 'Run the release in dry run mode, without pushing any changes'
name: Manually trigger a release
jobs:
release:
name: Trigger a release
runs-on: ubuntu-latest
env:
GITHUB_TOKEN: ${{ secrets.EXPO_BOT_PAT }}
INPUT_VERSION: ${{ github.event.inputs.version }}
INPUT_DRY_RUN: ${{ github.event.inputs.dry_run }}
steps:
- uses: actions/checkout@v4
with:
ref: main
fetch-depth: 0
token: ${{ secrets.EXPO_BOT_PAT }}
- uses: actions/setup-node@v4
with:
node-version: 22
- run: |
# Lerna will not detect changes correctly without having all tags
git fetch --depth=1 origin +refs/tags/*:refs/tags/*
# Checkout the main branch
git checkout main
git config --global user.email "[email protected]"
git config --global user.name "Expo CI"
yarn install --frozen-lockfile --check-files
yarn build
if [[ "$INPUT_VERSION" == "" ]]; then
echo "Releasing with default version"
yarn release
else
echo "Releasing with version $INPUT_VERSION"
yarn release $INPUT_VERSION
fi
-60
View File
@@ -11,66 +11,6 @@ This is the log of notable changes to EAS CLI and related packages.
### 🐛 Bug fixes
### 🧹 Chores
- Create an `EnvironmentVariableEnvironment` enum and use it instead of the graphQL Enum ([#3208](https://github.com/expo/eas-cli/pull/3208) by [@kadikraman](https://github.com/kadikraman))
## [16.20.1](https://github.com/expo/eas-cli/releases/tag/v16.20.1) - 2025-10-03
### 🐛 Bug fixes
- skip syncing capabilities with settings if they don't contain the `enabled` attribute ([#3201](https://github.com/expo/eas-cli/pull/3201) by [@vonovak](https://github.com/vonovak))
## [16.20.0](https://github.com/expo/eas-cli/releases/tag/v16.20.0) - 2025-09-30
### 🎉 New features
- Improvements to workflow:validate. ([#3165](https://github.com/expo/eas-cli/pull/3165) by [@douglowder](https://github.com/douglowder))
- Add `eas:new` command behind `hidden` flag. ([#3196](https://github.com/expo/eas-cli/pull/3196) by [@mackenco](https://github.com/mackenco))
## [16.19.3](https://github.com/expo/eas-cli/releases/tag/v16.19.3) - 2025-09-17
### 🧹 Chores
- Temporarily remove warnings when no compatible build found, need to refine the message. ([#3182](https://github.com/expo/eas-cli/pull/3182) by [@brentvatne](https://github.com/brentvatne))
## [16.19.2](https://github.com/expo/eas-cli/releases/tag/v16.19.2) - 2025-09-15
### 🎉 New features
- Add artifact URLs to workflow:view. ([#3175](https://github.com/expo/eas-cli/pull/3175) by [@douglowder](https://github.com/douglowder))
## [16.19.1](https://github.com/expo/eas-cli/releases/tag/v16.19.1) - 2025-09-12
## [16.19.0](https://github.com/expo/eas-cli/releases/tag/v16.19.0) - 2025-09-12
### 🎉 New features
- Allow any string as Android release `track`, not just the `production`, `internal`, `alpha`, `beta`. ([#3163](https://github.com/expo/eas-cli/pull/3163) by [@sjchmiela](https://github.com/sjchmiela))
## [16.18.1](https://github.com/expo/eas-cli/releases/tag/v16.18.1) - 2025-09-10
### 🎉 New features
- CLI debug log should respect DEBUG=`eas:*`. ([#3162](https://github.com/expo/eas-cli/pull/3162) by [@douglowder](https://github.com/douglowder))
- Better description for update:rollback. ([#3154](https://github.com/expo/eas-cli/pull/3154) by [@douglowder](https://github.com/douglowder))
## [16.18.0](https://github.com/expo/eas-cli/releases/tag/v16.18.0) - 2025-08-27
### 🎉 New features
- Show fingerprints in build:view and build:list commands. ([#3137](https://github.com/expo/eas-cli/pull/3137) by [@douglowder](https://github.com/douglowder))
### 🐛 Bug fixes
- Make `EXPO_PUBLIC_` env vars plain text, rest sensitive ([#3121](https://github.com/expo/eas-cli/pull/3121) by [@kadikraman](https://github.com/kadikraman))
## [16.17.4](https://github.com/expo/eas-cli/releases/tag/v16.17.4) - 2025-07-31
### 🧹 Chores
- Introduce new release process and workflow. ([#3119](https://github.com/expo/eas-cli/pull/3119) by [@douglowder](https://github.com/douglowder))
- SSO Login: print browser url ([#3113](https://github.com/expo/eas-cli/pull/3113) by [@BackSlasher](https://github.com/BackSlasher))
## [16.17.2](https://github.com/expo/eas-cli/releases/tag/v16.17.2) - 2025-07-23
## [16.17.1](https://github.com/expo/eas-cli/releases/tag/v16.17.1) - 2025-07-23
+5 -14
View File
@@ -1,21 +1,12 @@
# Development
## Getting Started
Set up an alias for the EAS CLI so you can try it in projects all around your computer. The project is compiled on the fly so you don't need to run a build (watch) command.
If this is your first time running `eas-cli` locally, make sure you install and build the packages. In the project root, run:
```sh
yarn install
yarn build
```
From there, set up an alias for the EAS CLI so you can try it in projects all around your computer. The project is compiled on the fly so you don't need to run a build (watch) command.
> The only exception is if there have been changes in `packages/eas-json`. In that case, you'll have to run `yarn build` in the root.
> The only exception is when you just cloned the repository or there have been changes in `packages/eas-json`. In that case, you'll have to run `yarn build` in the root.
Open your `.zshrc` or other config file and add:
```sh
```
alias easd="/PATH/TO/eas-cli/bin/run"
```
@@ -23,7 +14,7 @@ Then use it with `easd` like `easd build`.
If you're making changes to `packages/eas-json` or prefer/need to work with production code, start the build command in watch mode with:
```sh
```
yarn start
```
@@ -42,7 +33,7 @@ If it is easier for you to work with the code locally with compiler options set
you can consider using:
```sh
```
yarn start-allow-unused
```
+1 -1
View File
@@ -1,6 +1,6 @@
# Releasing EAS CLI
1. Invoke the GitHub workflow ["Manually trigger a release"](https://github.com/expo/eas-cli/actions/workflows/trigger-release.yml). The next version is chosen automatically based on the changelog entries. If you want to use different version, pass the version string as an input to the workflow, in semver format, e.g. "1.2.3"
1. Run `yarn release` in the repository root folder. The next version is chosen automatically based on the changelog entries. If you want to use different version, pass the version string as a positional argument to the command, e.g. `yarn release 1.2.3`.
2. That's it! GitHub Actions is going to take care of the rest. Watch the #eas-cli Slack channel for a successful release notification.
## Choosing the next version
+1 -1
View File
@@ -1,5 +1,5 @@
{
"npmClient": "yarn",
"version": "16.20.2",
"version": "16.17.2",
"$schema": "node_modules/lerna/schemas/lerna-schema.json"
}
+90 -113
View File
@@ -81,7 +81,6 @@ eas --help COMMAND
* [`eas build:version:sync`](#eas-buildversionsync)
* [`eas build:view [BUILD_ID]`](#eas-buildview-build_id)
* [`eas channel:create [NAME]`](#eas-channelcreate-name)
* [`eas channel:delete [NAME]`](#eas-channeldelete-name)
* [`eas channel:edit [NAME]`](#eas-channeledit-name)
* [`eas channel:list`](#eas-channellist)
* [`eas channel:pause [NAME]`](#eas-channelpause-name)
@@ -91,7 +90,7 @@ eas --help COMMAND
* [`eas config`](#eas-config)
* [`eas credentials`](#eas-credentials)
* [`eas credentials:configure-build`](#eas-credentialsconfigure-build)
* [`eas deploy [options]`](#eas-deploy-options)
* [`eas deploy [options]`](#eas-deploy-2moptions22m)
* [`eas deploy:alias`](#eas-deployalias)
* [`eas deploy:alias:delete [ALIAS_NAME]`](#eas-deployaliasdelete-alias_name)
* [`eas deploy:delete [DEPLOYMENT_ID]`](#eas-deploydelete-deployment_id)
@@ -146,7 +145,7 @@ eas --help COMMAND
* [`eas worker:alias`](#eas-workeralias)
* [`eas worker:alias:delete [ALIAS_NAME]`](#eas-workeraliasdelete-alias_name)
* [`eas worker:delete [DEPLOYMENT_ID]`](#eas-workerdelete-deployment_id)
* [`eas deploy [options]`](#eas-deploy-options-1)
* [`eas deploy [options]`](#eas-deploy-2moptions22m-1)
* [`eas workflow:cancel`](#eas-workflowcancel)
* [`eas workflow:create [NAME]`](#eas-workflowcreate-name)
* [`eas workflow:logs [ID]`](#eas-workflowlogs-id)
@@ -173,7 +172,7 @@ ALIASES
$ eas login
```
_See code: [packages/eas-cli/src/commands/account/login.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/account/login.ts)_
_See code: [packages/eas-cli/src/commands/account/login.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/account/login.ts)_
## `eas account:logout`
@@ -190,7 +189,7 @@ ALIASES
$ eas logout
```
_See code: [packages/eas-cli/src/commands/account/logout.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/account/logout.ts)_
_See code: [packages/eas-cli/src/commands/account/logout.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/account/logout.ts)_
## `eas account:view`
@@ -207,7 +206,7 @@ ALIASES
$ eas whoami
```
_See code: [packages/eas-cli/src/commands/account/view.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/account/view.ts)_
_See code: [packages/eas-cli/src/commands/account/view.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/account/view.ts)_
## `eas analytics [STATUS]`
@@ -221,7 +220,7 @@ DESCRIPTION
display or change analytics settings
```
_See code: [packages/eas-cli/src/commands/analytics.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/analytics.ts)_
_See code: [packages/eas-cli/src/commands/analytics.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/analytics.ts)_
## `eas autocomplete [SHELL]`
@@ -273,7 +272,7 @@ DESCRIPTION
create a branch
```
_See code: [packages/eas-cli/src/commands/branch/create.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/branch/create.ts)_
_See code: [packages/eas-cli/src/commands/branch/create.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/branch/create.ts)_
## `eas branch:delete [NAME]`
@@ -294,7 +293,7 @@ DESCRIPTION
delete a branch
```
_See code: [packages/eas-cli/src/commands/branch/delete.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/branch/delete.ts)_
_See code: [packages/eas-cli/src/commands/branch/delete.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/branch/delete.ts)_
## `eas branch:list`
@@ -314,7 +313,7 @@ DESCRIPTION
list all branches
```
_See code: [packages/eas-cli/src/commands/branch/list.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/branch/list.ts)_
_See code: [packages/eas-cli/src/commands/branch/list.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/branch/list.ts)_
## `eas branch:rename`
@@ -334,7 +333,7 @@ DESCRIPTION
rename a branch
```
_See code: [packages/eas-cli/src/commands/branch/rename.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/branch/rename.ts)_
_See code: [packages/eas-cli/src/commands/branch/rename.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/branch/rename.ts)_
## `eas branch:view [NAME]`
@@ -357,7 +356,7 @@ DESCRIPTION
view a branch
```
_See code: [packages/eas-cli/src/commands/branch/view.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/branch/view.ts)_
_See code: [packages/eas-cli/src/commands/branch/view.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/branch/view.ts)_
## `eas build`
@@ -398,7 +397,7 @@ DESCRIPTION
start a build
```
_See code: [packages/eas-cli/src/commands/build/index.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/build/index.ts)_
_See code: [packages/eas-cli/src/commands/build/index.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/build/index.ts)_
## `eas build:cancel [BUILD_ID]`
@@ -417,7 +416,7 @@ DESCRIPTION
cancel a build
```
_See code: [packages/eas-cli/src/commands/build/cancel.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/build/cancel.ts)_
_See code: [packages/eas-cli/src/commands/build/cancel.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/build/cancel.ts)_
## `eas build:configure`
@@ -434,7 +433,7 @@ DESCRIPTION
configure the project to support EAS Build
```
_See code: [packages/eas-cli/src/commands/build/configure.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/build/configure.ts)_
_See code: [packages/eas-cli/src/commands/build/configure.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/build/configure.ts)_
## `eas build:delete [BUILD_ID]`
@@ -453,7 +452,7 @@ DESCRIPTION
delete a build
```
_See code: [packages/eas-cli/src/commands/build/delete.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/build/delete.ts)_
_See code: [packages/eas-cli/src/commands/build/delete.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/build/delete.ts)_
## `eas build:dev`
@@ -473,7 +472,7 @@ DESCRIPTION
run dev client simulator/emulator build with matching fingerprint or create a new one
```
_See code: [packages/eas-cli/src/commands/build/dev.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/build/dev.ts)_
_See code: [packages/eas-cli/src/commands/build/dev.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/build/dev.ts)_
## `eas build:download`
@@ -494,7 +493,7 @@ DESCRIPTION
download simulator/emulator builds for a given fingerprint hash
```
_See code: [packages/eas-cli/src/commands/build/download.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/build/download.ts)_
_See code: [packages/eas-cli/src/commands/build/download.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/build/download.ts)_
## `eas build:inspect`
@@ -529,7 +528,7 @@ DESCRIPTION
inspect the state of the project at specific build stages, useful for troubleshooting
```
_See code: [packages/eas-cli/src/commands/build/inspect.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/build/inspect.ts)_
_See code: [packages/eas-cli/src/commands/build/inspect.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/build/inspect.ts)_
## `eas build:list`
@@ -581,7 +580,7 @@ DESCRIPTION
list all builds for your project
```
_See code: [packages/eas-cli/src/commands/build/list.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/build/list.ts)_
_See code: [packages/eas-cli/src/commands/build/list.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/build/list.ts)_
## `eas build:resign`
@@ -610,7 +609,7 @@ DESCRIPTION
re-sign a build archive
```
_See code: [packages/eas-cli/src/commands/build/resign.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/build/resign.ts)_
_See code: [packages/eas-cli/src/commands/build/resign.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/build/resign.ts)_
## `eas build:run`
@@ -636,7 +635,7 @@ DESCRIPTION
run simulator/emulator builds from eas-cli
```
_See code: [packages/eas-cli/src/commands/build/run.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/build/run.ts)_
_See code: [packages/eas-cli/src/commands/build/run.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/build/run.ts)_
## `eas build:submit`
@@ -690,7 +689,7 @@ DESCRIPTION
get the latest version from EAS servers
```
_See code: [packages/eas-cli/src/commands/build/version/get.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/build/version/get.ts)_
_See code: [packages/eas-cli/src/commands/build/version/get.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/build/version/get.ts)_
## `eas build:version:set`
@@ -709,7 +708,7 @@ DESCRIPTION
update version of an app
```
_See code: [packages/eas-cli/src/commands/build/version/set.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/build/version/set.ts)_
_See code: [packages/eas-cli/src/commands/build/version/set.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/build/version/set.ts)_
## `eas build:version:sync`
@@ -728,7 +727,7 @@ DESCRIPTION
update a version in native code with a value stored on EAS servers
```
_See code: [packages/eas-cli/src/commands/build/version/sync.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/build/version/sync.ts)_
_See code: [packages/eas-cli/src/commands/build/version/sync.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/build/version/sync.ts)_
## `eas build:view [BUILD_ID]`
@@ -745,7 +744,7 @@ DESCRIPTION
view a build for your project
```
_See code: [packages/eas-cli/src/commands/build/view.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/build/view.ts)_
_See code: [packages/eas-cli/src/commands/build/view.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/build/view.ts)_
## `eas channel:create [NAME]`
@@ -766,28 +765,7 @@ DESCRIPTION
create a channel
```
_See code: [packages/eas-cli/src/commands/channel/create.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/channel/create.ts)_
## `eas channel:delete [NAME]`
Delete a channel
```
USAGE
$ eas channel:delete [NAME] [--json --non-interactive]
ARGUMENTS
NAME Name of the channel to delete
FLAGS
--json Enable JSON output, non-JSON messages will be printed to stderr.
--non-interactive Run the command in non-interactive mode.
DESCRIPTION
Delete a channel
```
_See code: [packages/eas-cli/src/commands/channel/delete.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/channel/delete.ts)_
_See code: [packages/eas-cli/src/commands/channel/create.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/channel/create.ts)_
## `eas channel:edit [NAME]`
@@ -809,7 +787,7 @@ DESCRIPTION
point a channel at a new branch
```
_See code: [packages/eas-cli/src/commands/channel/edit.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/channel/edit.ts)_
_See code: [packages/eas-cli/src/commands/channel/edit.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/channel/edit.ts)_
## `eas channel:list`
@@ -829,7 +807,7 @@ DESCRIPTION
list all channels
```
_See code: [packages/eas-cli/src/commands/channel/list.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/channel/list.ts)_
_See code: [packages/eas-cli/src/commands/channel/list.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/channel/list.ts)_
## `eas channel:pause [NAME]`
@@ -851,7 +829,7 @@ DESCRIPTION
pause a channel to stop it from sending updates
```
_See code: [packages/eas-cli/src/commands/channel/pause.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/channel/pause.ts)_
_See code: [packages/eas-cli/src/commands/channel/pause.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/channel/pause.ts)_
## `eas channel:resume [NAME]`
@@ -873,7 +851,7 @@ DESCRIPTION
resume a channel to start sending updates
```
_See code: [packages/eas-cli/src/commands/channel/resume.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/channel/resume.ts)_
_See code: [packages/eas-cli/src/commands/channel/resume.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/channel/resume.ts)_
## `eas channel:rollout [CHANNEL]`
@@ -906,7 +884,7 @@ DESCRIPTION
Roll a new branch out on a channel incrementally.
```
_See code: [packages/eas-cli/src/commands/channel/rollout.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/channel/rollout.ts)_
_See code: [packages/eas-cli/src/commands/channel/rollout.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/channel/rollout.ts)_
## `eas channel:view [NAME]`
@@ -929,7 +907,7 @@ DESCRIPTION
view a channel
```
_See code: [packages/eas-cli/src/commands/channel/view.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/channel/view.ts)_
_See code: [packages/eas-cli/src/commands/channel/view.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/channel/view.ts)_
## `eas config`
@@ -950,7 +928,7 @@ DESCRIPTION
display project configuration (app.json + eas.json)
```
_See code: [packages/eas-cli/src/commands/config.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/config.ts)_
_See code: [packages/eas-cli/src/commands/config.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/config.ts)_
## `eas credentials`
@@ -967,7 +945,7 @@ DESCRIPTION
manage credentials
```
_See code: [packages/eas-cli/src/commands/credentials/index.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/credentials/index.ts)_
_See code: [packages/eas-cli/src/commands/credentials/index.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/credentials/index.ts)_
## `eas credentials:configure-build`
@@ -985,9 +963,9 @@ DESCRIPTION
Set up credentials for building your project.
```
_See code: [packages/eas-cli/src/commands/credentials/configure-build.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/credentials/configure-build.ts)_
_See code: [packages/eas-cli/src/commands/credentials/configure-build.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/credentials/configure-build.ts)_
## `eas deploy [options]`
## `eas deploy [options]`
deploy your Expo Router web build and API Routes
@@ -1013,7 +991,7 @@ ALIASES
$ eas worker:deploy
```
_See code: [packages/eas-cli/src/commands/deploy/index.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/deploy/index.ts)_
_See code: [packages/eas-cli/src/commands/deploy/index.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/deploy/index.ts)_
## `eas deploy:alias`
@@ -1038,7 +1016,7 @@ ALIASES
$ eas deploy:promote
```
_See code: [packages/eas-cli/src/commands/deploy/alias/index.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/deploy/alias/index.ts)_
_See code: [packages/eas-cli/src/commands/deploy/alias/index.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/deploy/alias/index.ts)_
## `eas deploy:alias:delete [ALIAS_NAME]`
@@ -1059,7 +1037,7 @@ ALIASES
$ eas worker:alias:delete
```
_See code: [packages/eas-cli/src/commands/deploy/alias/delete.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/deploy/alias/delete.ts)_
_See code: [packages/eas-cli/src/commands/deploy/alias/delete.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/deploy/alias/delete.ts)_
## `eas deploy:delete [DEPLOYMENT_ID]`
@@ -1080,7 +1058,7 @@ ALIASES
$ eas worker:delete
```
_See code: [packages/eas-cli/src/commands/deploy/delete.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/deploy/delete.ts)_
_See code: [packages/eas-cli/src/commands/deploy/delete.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/deploy/delete.ts)_
## `eas deploy:promote`
@@ -1117,7 +1095,7 @@ DESCRIPTION
register new Apple Devices to use for internal distribution
```
_See code: [packages/eas-cli/src/commands/device/create.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/device/create.ts)_
_See code: [packages/eas-cli/src/commands/device/create.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/device/create.ts)_
## `eas device:delete`
@@ -1137,7 +1115,7 @@ DESCRIPTION
remove a registered device from your account
```
_See code: [packages/eas-cli/src/commands/device/delete.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/device/delete.ts)_
_See code: [packages/eas-cli/src/commands/device/delete.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/device/delete.ts)_
## `eas device:list`
@@ -1158,7 +1136,7 @@ DESCRIPTION
list all registered devices for your account
```
_See code: [packages/eas-cli/src/commands/device/list.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/device/list.ts)_
_See code: [packages/eas-cli/src/commands/device/list.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/device/list.ts)_
## `eas device:rename`
@@ -1179,7 +1157,7 @@ DESCRIPTION
rename a registered device
```
_See code: [packages/eas-cli/src/commands/device/rename.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/device/rename.ts)_
_See code: [packages/eas-cli/src/commands/device/rename.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/device/rename.ts)_
## `eas device:view [UDID]`
@@ -1193,7 +1171,7 @@ DESCRIPTION
view a device for your project
```
_See code: [packages/eas-cli/src/commands/device/view.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/device/view.ts)_
_See code: [packages/eas-cli/src/commands/device/view.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/device/view.ts)_
## `eas diagnostics`
@@ -1207,7 +1185,7 @@ DESCRIPTION
display environment info
```
_See code: [packages/eas-cli/src/commands/diagnostics.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/diagnostics.ts)_
_See code: [packages/eas-cli/src/commands/diagnostics.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/diagnostics.ts)_
## `eas env:create [ENVIRONMENT]`
@@ -1236,7 +1214,7 @@ DESCRIPTION
create an environment variable for the current project or account
```
_See code: [packages/eas-cli/src/commands/env/create.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/env/create.ts)_
_See code: [packages/eas-cli/src/commands/env/create.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/env/create.ts)_
## `eas env:delete [ENVIRONMENT]`
@@ -1260,7 +1238,7 @@ DESCRIPTION
delete an environment variable for the current project or account
```
_See code: [packages/eas-cli/src/commands/env/delete.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/env/delete.ts)_
_See code: [packages/eas-cli/src/commands/env/delete.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/env/delete.ts)_
## `eas env:exec ENVIRONMENT BASH_COMMAND`
@@ -1281,7 +1259,7 @@ DESCRIPTION
execute a command with environment variables from the selected environment
```
_See code: [packages/eas-cli/src/commands/env/exec.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/env/exec.ts)_
_See code: [packages/eas-cli/src/commands/env/exec.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/env/exec.ts)_
## `eas env:get [ENVIRONMENT]`
@@ -1306,7 +1284,7 @@ DESCRIPTION
view an environment variable for the current project or account
```
_See code: [packages/eas-cli/src/commands/env/get.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/env/get.ts)_
_See code: [packages/eas-cli/src/commands/env/get.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/env/get.ts)_
## `eas env:list [ENVIRONMENT]`
@@ -1331,7 +1309,7 @@ DESCRIPTION
list environment variables for the current project or account
```
_See code: [packages/eas-cli/src/commands/env/list.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/env/list.ts)_
_See code: [packages/eas-cli/src/commands/env/list.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/env/list.ts)_
## `eas env:pull [ENVIRONMENT]`
@@ -1354,7 +1332,7 @@ DESCRIPTION
pull environment variables for the selected environment to .env file
```
_See code: [packages/eas-cli/src/commands/env/pull.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/env/pull.ts)_
_See code: [packages/eas-cli/src/commands/env/pull.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/env/pull.ts)_
## `eas env:push [ENVIRONMENT]`
@@ -1375,7 +1353,7 @@ DESCRIPTION
push environment variables from .env file to the selected environment
```
_See code: [packages/eas-cli/src/commands/env/push.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/env/push.ts)_
_See code: [packages/eas-cli/src/commands/env/push.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/env/push.ts)_
## `eas env:update [ENVIRONMENT]`
@@ -1406,7 +1384,7 @@ DESCRIPTION
update an environment variable on the current project or account
```
_See code: [packages/eas-cli/src/commands/env/update.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/env/update.ts)_
_See code: [packages/eas-cli/src/commands/env/update.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/env/update.ts)_
## `eas fingerprint:compare [HASH1] [HASH2]`
@@ -1451,7 +1429,7 @@ EXAMPLES
$ eas fingerprint:compare <FINGERPRINT-HASH> --update-id <UPDATE-ID> # Compare fingerprint from update against provided fingerprint
```
_See code: [packages/eas-cli/src/commands/fingerprint/compare.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/fingerprint/compare.ts)_
_See code: [packages/eas-cli/src/commands/fingerprint/compare.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/fingerprint/compare.ts)_
## `eas fingerprint:generate`
@@ -1482,7 +1460,7 @@ EXAMPLES
$ eas fingerprint:generate --json --non-interactive --platform android # Output fingerprint json to stdout
```
_See code: [packages/eas-cli/src/commands/fingerprint/generate.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/fingerprint/generate.ts)_
_See code: [packages/eas-cli/src/commands/fingerprint/generate.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/fingerprint/generate.ts)_
## `eas help [COMMAND]`
@@ -1590,7 +1568,7 @@ DESCRIPTION
validate the local store configuration
```
_See code: [packages/eas-cli/src/commands/metadata/lint.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/metadata/lint.ts)_
_See code: [packages/eas-cli/src/commands/metadata/lint.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/metadata/lint.ts)_
## `eas metadata:pull`
@@ -1607,7 +1585,7 @@ DESCRIPTION
generate the local store configuration from the app stores
```
_See code: [packages/eas-cli/src/commands/metadata/pull.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/metadata/pull.ts)_
_See code: [packages/eas-cli/src/commands/metadata/pull.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/metadata/pull.ts)_
## `eas metadata:push`
@@ -1624,7 +1602,7 @@ DESCRIPTION
sync the local store configuration to the app stores
```
_See code: [packages/eas-cli/src/commands/metadata/push.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/metadata/push.ts)_
_See code: [packages/eas-cli/src/commands/metadata/push.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/metadata/push.ts)_
## `eas onboarding [TARGET_PROJECT_DIRECTORY]`
@@ -1654,7 +1632,7 @@ DESCRIPTION
open the project page in a web browser
```
_See code: [packages/eas-cli/src/commands/open.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/open.ts)_
_See code: [packages/eas-cli/src/commands/open.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/open.ts)_
## `eas project:info`
@@ -1668,7 +1646,7 @@ DESCRIPTION
information about the current project
```
_See code: [packages/eas-cli/src/commands/project/info.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/project/info.ts)_
_See code: [packages/eas-cli/src/commands/project/info.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/project/info.ts)_
## `eas project:init`
@@ -1691,7 +1669,7 @@ ALIASES
$ eas init
```
_See code: [packages/eas-cli/src/commands/project/init.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/project/init.ts)_
_See code: [packages/eas-cli/src/commands/project/init.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/project/init.ts)_
## `eas project:onboarding [TARGET_PROJECT_DIRECTORY]`
@@ -1709,7 +1687,7 @@ ALIASES
$ eas onboarding
```
_See code: [packages/eas-cli/src/commands/project/onboarding.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/project/onboarding.ts)_
_See code: [packages/eas-cli/src/commands/project/onboarding.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/project/onboarding.ts)_
## `eas submit`
@@ -1744,7 +1722,7 @@ ALIASES
$ eas build:submit
```
_See code: [packages/eas-cli/src/commands/submit.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/submit.ts)_
_See code: [packages/eas-cli/src/commands/submit.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/submit.ts)_
## `eas update`
@@ -1786,7 +1764,7 @@ DESCRIPTION
publish an update group
```
_See code: [packages/eas-cli/src/commands/update/index.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/update/index.ts)_
_See code: [packages/eas-cli/src/commands/update/index.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/update/index.ts)_
## `eas update:configure`
@@ -1806,7 +1784,7 @@ DESCRIPTION
configure the project to support EAS Update
```
_See code: [packages/eas-cli/src/commands/update/configure.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/update/configure.ts)_
_See code: [packages/eas-cli/src/commands/update/configure.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/update/configure.ts)_
## `eas update:delete GROUPID`
@@ -1827,7 +1805,7 @@ DESCRIPTION
delete all the updates in an update group
```
_See code: [packages/eas-cli/src/commands/update/delete.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/update/delete.ts)_
_See code: [packages/eas-cli/src/commands/update/delete.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/update/delete.ts)_
## `eas update:edit [GROUPID]`
@@ -1851,7 +1829,7 @@ DESCRIPTION
edit all the updates in an update group
```
_See code: [packages/eas-cli/src/commands/update/edit.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/update/edit.ts)_
_See code: [packages/eas-cli/src/commands/update/edit.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/update/edit.ts)_
## `eas update:list`
@@ -1873,7 +1851,7 @@ DESCRIPTION
view the recent updates
```
_See code: [packages/eas-cli/src/commands/update/list.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/update/list.ts)_
_See code: [packages/eas-cli/src/commands/update/list.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/update/list.ts)_
## `eas update:republish`
@@ -1909,7 +1887,7 @@ DESCRIPTION
roll back to an existing update
```
_See code: [packages/eas-cli/src/commands/update/republish.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/update/republish.ts)_
_See code: [packages/eas-cli/src/commands/update/republish.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/update/republish.ts)_
## `eas update:revert-update-rollout`
@@ -1936,7 +1914,7 @@ DESCRIPTION
revert a rollout update for a project
```
_See code: [packages/eas-cli/src/commands/update/revert-update-rollout.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/update/revert-update-rollout.ts)_
_See code: [packages/eas-cli/src/commands/update/revert-update-rollout.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/update/revert-update-rollout.ts)_
## `eas update:roll-back-to-embedded`
@@ -1964,11 +1942,11 @@ DESCRIPTION
roll back to the embedded update
```
_See code: [packages/eas-cli/src/commands/update/roll-back-to-embedded.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/update/roll-back-to-embedded.ts)_
_See code: [packages/eas-cli/src/commands/update/roll-back-to-embedded.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/update/roll-back-to-embedded.ts)_
## `eas update:rollback`
Roll back to an embedded update or an existing update. Users wishing to run this command non-interactively should instead execute "eas update:republish" or "eas update:roll-back-to-embedded".
roll back to an embedded update or an existing update
```
USAGE
@@ -1981,11 +1959,10 @@ FLAGS
https://docs.expo.dev/eas-update/code-signing/
DESCRIPTION
Roll back to an embedded update or an existing update. Users wishing to run this command non-interactively should
instead execute "eas update:republish" or "eas update:roll-back-to-embedded".
roll back to an embedded update or an existing update
```
_See code: [packages/eas-cli/src/commands/update/rollback.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/update/rollback.ts)_
_See code: [packages/eas-cli/src/commands/update/rollback.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/update/rollback.ts)_
## `eas update:view GROUPID`
@@ -2005,7 +1982,7 @@ DESCRIPTION
update group details
```
_See code: [packages/eas-cli/src/commands/update/view.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/update/view.ts)_
_See code: [packages/eas-cli/src/commands/update/view.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/update/view.ts)_
## `eas upload`
@@ -2026,7 +2003,7 @@ DESCRIPTION
upload a local build and generate a sharable link
```
_See code: [packages/eas-cli/src/commands/upload.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/upload.ts)_
_See code: [packages/eas-cli/src/commands/upload.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/upload.ts)_
## `eas webhook:create`
@@ -2047,7 +2024,7 @@ DESCRIPTION
create a webhook
```
_See code: [packages/eas-cli/src/commands/webhook/create.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/webhook/create.ts)_
_See code: [packages/eas-cli/src/commands/webhook/create.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/webhook/create.ts)_
## `eas webhook:delete [ID]`
@@ -2067,7 +2044,7 @@ DESCRIPTION
delete a webhook
```
_See code: [packages/eas-cli/src/commands/webhook/delete.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/webhook/delete.ts)_
_See code: [packages/eas-cli/src/commands/webhook/delete.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/webhook/delete.ts)_
## `eas webhook:list`
@@ -2085,7 +2062,7 @@ DESCRIPTION
list webhooks
```
_See code: [packages/eas-cli/src/commands/webhook/list.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/webhook/list.ts)_
_See code: [packages/eas-cli/src/commands/webhook/list.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/webhook/list.ts)_
## `eas webhook:update`
@@ -2107,7 +2084,7 @@ DESCRIPTION
update a webhook
```
_See code: [packages/eas-cli/src/commands/webhook/update.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/webhook/update.ts)_
_See code: [packages/eas-cli/src/commands/webhook/update.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/webhook/update.ts)_
## `eas webhook:view ID`
@@ -2124,7 +2101,7 @@ DESCRIPTION
view a webhook
```
_See code: [packages/eas-cli/src/commands/webhook/view.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/webhook/view.ts)_
_See code: [packages/eas-cli/src/commands/webhook/view.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/webhook/view.ts)_
## `eas whoami`
@@ -2202,7 +2179,7 @@ ALIASES
$ eas worker:delete
```
## `eas deploy [options]`
## `eas deploy [options]`
deploy your Expo Router web build and API Routes
@@ -2244,7 +2221,7 @@ DESCRIPTION
to cancel.
```
_See code: [packages/eas-cli/src/commands/workflow/cancel.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/workflow/cancel.ts)_
_See code: [packages/eas-cli/src/commands/workflow/cancel.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/workflow/cancel.ts)_
## `eas workflow:create [NAME]`
@@ -2264,7 +2241,7 @@ DESCRIPTION
create a new workflow configuration YAML file
```
_See code: [packages/eas-cli/src/commands/workflow/create.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/workflow/create.ts)_
_See code: [packages/eas-cli/src/commands/workflow/create.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/workflow/create.ts)_
## `eas workflow:logs [ID]`
@@ -2288,7 +2265,7 @@ DESCRIPTION
If no ID is passed in, you will be prompted to select from recent workflow runs for the current project.
```
_See code: [packages/eas-cli/src/commands/workflow/logs.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/workflow/logs.ts)_
_See code: [packages/eas-cli/src/commands/workflow/logs.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/workflow/logs.ts)_
## `eas workflow:run [FILE]`
@@ -2320,7 +2297,7 @@ FLAG DESCRIPTIONS
Exit codes: 0 = success, 11 = failure, 12 = canceled, 13 = wait aborted.
```
_See code: [packages/eas-cli/src/commands/workflow/run.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/workflow/run.ts)_
_See code: [packages/eas-cli/src/commands/workflow/run.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/workflow/run.ts)_
## `eas workflow:runs`
@@ -2345,7 +2322,7 @@ DESCRIPTION
list recent workflow runs for this project, with their IDs, statuses, and timestamps
```
_See code: [packages/eas-cli/src/commands/workflow/runs.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/workflow/runs.ts)_
_See code: [packages/eas-cli/src/commands/workflow/runs.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/workflow/runs.ts)_
## `eas workflow:validate PATH`
@@ -2365,7 +2342,7 @@ DESCRIPTION
validate a workflow configuration yaml file
```
_See code: [packages/eas-cli/src/commands/workflow/validate.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/workflow/validate.ts)_
_See code: [packages/eas-cli/src/commands/workflow/validate.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/workflow/validate.ts)_
## `eas workflow:view [ID]`
@@ -2387,5 +2364,5 @@ DESCRIPTION
workflow runs for the current project.
```
_See code: [packages/eas-cli/src/commands/workflow/view.ts](https://github.com/expo/eas-cli/blob/v16.20.2/packages/eas-cli/src/commands/workflow/view.ts)_
_See code: [packages/eas-cli/src/commands/workflow/view.ts](https://github.com/expo/eas-cli/blob/v16.17.2/packages/eas-cli/src/commands/workflow/view.ts)_
<!-- commandsstop -->
+374 -779
View File
File diff suppressed because it is too large. Load diff
+7 -7
View File
@@ -1,7 +1,7 @@
{
"name": "eas-cli",
"description": "EAS command line tool",
"version": "16.20.2",
"version": "16.17.2",
"author": "Expo <[email protected]>",
"bin": {
"eas": "./bin/run"
@@ -12,11 +12,11 @@
"@expo/code-signing-certificates": "0.0.5",
"@expo/config": "10.0.6",
"@expo/config-plugins": "9.0.12",
"@expo/eas-build-job": "1.0.231",
"@expo/eas-json": "16.20.1",
"@expo/eas-build-job": "1.0.173",
"@expo/eas-json": "16.13.2",
"@expo/env": "^1.0.0",
"@expo/json-file": "8.3.3",
"@expo/logger": "1.0.221",
"@expo/logger": "1.0.117",
"@expo/multipart-body-parser": "2.0.0",
"@expo/osascript": "2.1.4",
"@expo/package-manager": "1.7.0",
@@ -28,7 +28,7 @@
"@expo/results": "1.0.0",
"@expo/rudder-sdk-node": "1.1.1",
"@expo/spawn-async": "1.7.2",
"@expo/steps": "1.0.231",
"@expo/steps": "1.0.173",
"@expo/timeago.js": "1.0.0",
"@oclif/core": "^1.26.2",
"@oclif/plugin-autocomplete": "^2.3.10",
@@ -85,14 +85,13 @@
"tar": "6.2.1",
"tar-stream": "3.1.7",
"terminal-link": "2.1.1",
"ts-deepmerge": "6.2.0",
"tslib": "2.6.2",
"turndown": "7.1.2",
"untildify": "4.0.0",
"uuid": "9.0.1",
"wrap-ansi": "7.0.0",
"yaml": "2.6.0",
"zod": "^4.1.3"
"zod": "^3.23.8"
},
"devDependencies": {
"@graphql-codegen/cli": "5.0.0",
@@ -127,6 +126,7 @@
"mockdate": "3.0.5",
"nock": "13.4.0",
"rimraf": "3.0.2",
"ts-deepmerge": "6.2.0",
"ts-mockito": "2.6.1",
"ts-node": "10.9.2",
"typescript": "5.3.3"
+1 -6
View File
@@ -25,12 +25,7 @@ if cmp -s graphql.schema.json graphql.schema.json.bak; then
exit 1
fi
else
echo "GraphQL schema has changed on the server."
echo "Building eas-json"
cd ../eas-json
yarn build
cd ../eas-cli
echo "Running `yarn tsc` to check for breaking changes..."
echo "GraphQL schema has changed on the server. Running `yarn tsc` to check for breaking changes..."
yarn tsc
# If there are no errors, then the schema is backwards compatible
exit 0
@@ -270,7 +270,6 @@ export function getMockWorkflowJobFragment(
id: 'job1',
logFileUrls: ['https://example.com/log1'],
errors: [],
artifacts: [],
},
};
}
-4
View File
@@ -108,7 +108,3 @@ export function getEASUpdateURL(projectId: string, manifestHostOverride: string
return new URL(projectId, `https://u.expo.dev`).href;
}
}
export function getExpoApiWorkflowSchemaURL(): string {
return getExpoApiBaseUrl() + '/v2/workflows/schema';
}
+5 -3
View File
@@ -1,4 +1,4 @@
import { Android, Platform, Workflow } from '@expo/eas-build-job';
import { Android, Metadata, Platform, Workflow } from '@expo/eas-build-job';
import { AppVersionSource } from '@expo/eas-json';
import chalk from 'chalk';
import getenv from 'getenv';
@@ -11,7 +11,7 @@ import { resolveRemoteVersionCodeAsync } from './version';
import AndroidCredentialsProvider, {
AndroidCredentials,
} from '../../credentials/android/AndroidCredentialsProvider';
import { BuildMetadataInput, BuildParamsInput } from '../../graphql/generated';
import { BuildParamsInput } from '../../graphql/generated';
import { BuildMutation, BuildResult } from '../../graphql/mutations/BuildMutation';
import Log, { learnMore } from '../../log';
import {
@@ -27,6 +27,7 @@ import {
prepareBuildRequestForPlatformAsync,
} from '../build';
import { AndroidBuildContext, BuildContext, CommonContext } from '../context';
import { transformMetadata } from '../graphql';
import { logCredentialsSource } from '../utils/credentials';
import {
checkGoogleServicesFileAsync,
@@ -123,9 +124,10 @@ export async function prepareAndroidBuildAsync(
sendBuildRequestAsync: async (
appId: string,
job: Android.Job,
graphqlMetadata: BuildMetadataInput,
metadata: Metadata,
buildParams: BuildParamsInput
): Promise<BuildResult> => {
const graphqlMetadata = transformMetadata(metadata);
const graphqlJob = transformJob(job);
return await BuildMutation.createAndroidBuildAsync(ctx.graphqlClient, {
appId,
+9 -17
View File
@@ -2,6 +2,7 @@ import {
ArchiveSource,
ArchiveSourceType,
BuildJob,
FingerprintSource,
Metadata,
Platform,
} from '@expo/eas-build-job';
@@ -49,11 +50,9 @@ import { createFingerprintAsync } from '../fingerprint/cli';
import {
AppPlatform,
BuildFragment,
BuildMetadataInput,
BuildParamsInput,
BuildPriority,
BuildStatus,
FingerprintSourceInput,
UploadSessionType,
} from '../graphql/generated';
import { BuildMutation, BuildResult } from '../graphql/mutations/BuildMutation';
@@ -95,7 +94,7 @@ interface Builder<TPlatform extends Platform, Credentials, TJob extends BuildJob
sendBuildRequestAsync(
appId: string,
job: TJob,
metadata: BuildMetadataInput,
metadata: Metadata,
buildParams: BuildParamsInput
): Promise<BuildResult>;
}
@@ -194,20 +193,13 @@ export async function prepareBuildRequestForPlatformAsync<
} else if (ctx.localBuildOptions.localBuildMode === LocalBuildMode.INTERNAL) {
await BuildMutation.updateBuildMetadataAsync(ctx.graphqlClient, {
buildId: nullthrows(process.env.EAS_BUILD_ID),
metadata: transformMetadata({
metadata,
fingerprintSource: runtimeAndFingerprintMetadata.fingerprintSource ?? undefined,
}),
metadata: transformMetadata(metadata),
});
printJsonOnlyOutput({ job, metadata });
return undefined;
} else if (!ctx.localBuildOptions.localBuildMode) {
try {
const graphqlMetadata = transformMetadata({
metadata,
fingerprintSource: runtimeAndFingerprintMetadata.fingerprintSource ?? undefined,
});
return await sendBuildRequestAsync(builder, job, graphqlMetadata, buildParams);
return await sendBuildRequestAsync(builder, job, metadata, buildParams);
} catch (error: any) {
handleBuildRequestError(error, job.platform);
}
@@ -370,7 +362,7 @@ async function sendBuildRequestAsync<
>(
builder: Builder<TPlatform, Credentials, TJob>,
job: TJob,
graphqlMetadata: BuildMetadataInput,
metadata: Metadata,
buildParams: BuildParamsInput
): Promise<BuildFragment> {
const { ctx } = builder;
@@ -384,7 +376,7 @@ async function sendBuildRequestAsync<
const { build, deprecationInfo } = await builder.sendBuildRequestAsync(
ctx.projectId,
job,
graphqlMetadata,
metadata,
buildParams
);
@@ -662,7 +654,7 @@ async function computeAndMaybeUploadRuntimeAndFingerprintMetadataAsync<T extends
): Promise<{
runtimeVersion?: string | undefined;
fingerprintHash?: string | undefined;
fingerprintSource?: FingerprintSourceInput | undefined;
fingerprintSource?: FingerprintSource | undefined;
}> {
const runtimeAndFingerprintMetadata =
await computeAndMaybeUploadFingerprintFromExpoUpdatesAsync(ctx);
@@ -684,7 +676,7 @@ async function computeAndMaybeUploadFingerprintFromExpoUpdatesAsync<T extends Pl
ctx: BuildContext<T>
): Promise<{
runtimeVersion?: string;
fingerprintSource?: FingerprintSourceInput;
fingerprintSource?: FingerprintSource;
fingerprintHash?: string;
}> {
const resolvedRuntimeVersion = await resolveRuntimeVersionAsync({
@@ -731,7 +723,7 @@ async function computeAndMaybeUploadFingerprintWithoutExpoUpdatesAsync<T extends
{ debug }: { debug?: boolean } = {}
): Promise<{
fingerprintHash?: string;
fingerprintSource?: FingerprintSourceInput;
fingerprintSource?: FingerprintSource;
}> {
const fingerprint = await createFingerprintAsync(ctx.projectDir, {
workflow: ctx.workflow,
@@ -1,8 +1,9 @@
import { Env } from '@expo/eas-build-job';
import { BuildProfile } from '@expo/eas-json';
import { EnvironmentVariableEnvironment, isEnvironment } from './utils/environment';
import { isEnvironment } from './utils/environment';
import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
import { EnvironmentVariableEnvironment } from '../graphql/generated';
import { EnvironmentVariablesQuery } from '../graphql/queries/EnvironmentVariablesQuery';
import Log, { learnMore } from '../log';
+19 -8
View File
@@ -3,6 +3,7 @@ import {
ArchiveSourceType,
BuildMode,
BuildTrigger,
FingerprintSourceType,
Metadata,
Workflow,
} from '@expo/eas-build-job';
@@ -18,6 +19,7 @@ import {
FingerprintSourceInput,
BuildMode as GraphQLBuildMode,
BuildTrigger as GraphQLBuildTrigger,
FingerprintSourceType as GraphQLFingeprintSourceType,
ProjectArchiveSourceInput,
ProjectArchiveSourceType,
WorkerLoggerLevel,
@@ -40,16 +42,11 @@ export function transformProjectArchive(archiveSource: ArchiveSource): ProjectAr
}
}
export function transformMetadata({
metadata,
fingerprintSource,
}: {
metadata: Metadata;
fingerprintSource: FingerprintSourceInput | undefined;
}): BuildMetadataInput {
export function transformMetadata(metadata: Metadata): BuildMetadataInput {
return {
...metadata,
fingerprintSource,
fingerprintSource:
metadata.fingerprintSource && transformFingerprintSource(metadata.fingerprintSource),
credentialsSource:
metadata.credentialsSource && transformCredentialsSource(metadata.credentialsSource),
distribution: metadata.distribution && transformDistribution(metadata.distribution),
@@ -60,6 +57,20 @@ export function transformMetadata({
};
}
export function transformFingerprintSource(
fingerprintSource: NonNullable<Metadata['fingerprintSource']>
): FingerprintSourceInput | null {
if (fingerprintSource.type !== FingerprintSourceType.GCS) {
return null;
}
return {
type: GraphQLFingeprintSourceType.Gcs,
bucketKey: fingerprintSource.bucketKey,
isDebugFingerprint: fingerprintSource.isDebugFingerprint,
};
}
function transformCredentialsSource(
credentialsSource: Metadata['credentialsSource']
): BuildCredentialsSource {
+5 -3
View File
@@ -1,4 +1,4 @@
import { Ios, Platform, Workflow } from '@expo/eas-build-job';
import { Ios, Metadata, Platform, Workflow } from '@expo/eas-build-job';
import { AppVersionSource } from '@expo/eas-json';
import { ensureIosCredentialsAsync } from './credentials';
@@ -7,7 +7,7 @@ import { prepareJobAsync } from './prepareJob';
import { syncProjectConfigurationAsync } from './syncProjectConfiguration';
import { resolveRemoteBuildNumberAsync } from './version';
import { IosCredentials } from '../../credentials/ios/types';
import { BuildMetadataInput, BuildParamsInput } from '../../graphql/generated';
import { BuildParamsInput } from '../../graphql/generated';
import { BuildMutation, BuildResult } from '../../graphql/mutations/BuildMutation';
import { ensureBundleIdentifierIsDefinedForManagedProjectAsync } from '../../project/ios/bundleIdentifier';
import { ensureNonExemptEncryptionIsDefinedForManagedProjectAsync } from '../../project/ios/exemptEncryption';
@@ -15,6 +15,7 @@ import { resolveXcodeBuildContextAsync } from '../../project/ios/scheme';
import { findApplicationTarget, resolveTargetsAsync } from '../../project/ios/target';
import { BuildRequestSender, JobData, prepareBuildRequestForPlatformAsync } from '../build';
import { BuildContext, CommonContext, IosBuildContext } from '../context';
import { transformMetadata } from '../graphql';
import {
checkGoogleServicesFileAsync,
checkNodeEnvVariable,
@@ -105,9 +106,10 @@ export async function prepareIosBuildAsync(
sendBuildRequestAsync: async (
appId: string,
job: Ios.Job,
graphqlMetadata: BuildMetadataInput,
metadata: Metadata,
buildParams: BuildParamsInput
): Promise<BuildResult> => {
const graphqlMetadata = transformMetadata(metadata);
const graphqlJob = transformJob(job);
return await BuildMutation.createIosBuildAsync(ctx.graphqlClient, {
appId,
+3 -1
View File
@@ -1,4 +1,4 @@
import { Metadata, Platform, sanitizeMetadata } from '@expo/eas-build-job';
import { FingerprintSource, Metadata, Platform, sanitizeMetadata } from '@expo/eas-build-job';
import { IosEnterpriseProvisioning } from '@expo/eas-json';
import fs from 'fs-extra';
import resolveFrom from 'resolve-from';
@@ -22,6 +22,7 @@ export async function collectMetadataAsync<T extends Platform>(
runtimeAndFingerprintMetadata: {
runtimeVersion?: string | undefined;
fingerprintHash?: string | undefined;
fingerprintSource?: FingerprintSource | undefined;
}
): Promise<Metadata> {
const channelObject = await resolveChannelAsync(ctx);
@@ -35,6 +36,7 @@ export async function collectMetadataAsync<T extends Platform>(
sdkVersion: ctx.exp.sdkVersion,
runtimeVersion: runtimeAndFingerprintMetadata?.runtimeVersion,
fingerprintHash: runtimeAndFingerprintMetadata?.fingerprintHash,
fingerprintSource: runtimeAndFingerprintMetadata?.fingerprintSource,
reactNativeVersion: await getReactNativeVersionAsync(ctx.projectDir),
...channelObject,
distribution,
@@ -1,13 +1,8 @@
import { BuildProfile } from '@expo/eas-json';
type Environment = NonNullable<BuildProfile['environment']>;
import { EnvironmentVariableEnvironment } from '../../graphql/generated';
// Default environments
export enum EnvironmentVariableEnvironment {
Development = 'development',
Preview = 'preview',
Production = 'production',
}
type Environment = NonNullable<BuildProfile['environment']>;
const BuildProfileEnvironmentToEnvironment: Record<Environment, EnvironmentVariableEnvironment> = {
production: EnvironmentVariableEnvironment.Production,
@@ -6,44 +6,8 @@ import {
BuildFragment,
BuildStatus as GraphQLBuildStatus,
} from '../../graphql/generated';
import { link } from '../../log';
import { appPlatformDisplayNames } from '../../platform';
import formatFields, { FormatFieldsItem } from '../../utils/formatFields';
export function formatGraphQLBuildArtifacts(build: BuildFragment): FormatFieldsItem[] {
const fields = [
{
label: 'Application Archive URL',
get value() {
switch (build.status) {
case GraphQLBuildStatus.InProgress:
return '<in progress>';
default: {
const url = build.artifacts?.buildUrl;
return url ? link(url) : 'null';
}
}
},
},
{
label: 'Build Artifacts URL',
get value() {
switch (build.status) {
case GraphQLBuildStatus.InProgress:
return '<in progress>';
default: {
const url = build.artifacts?.buildArtifactsUrl;
return url ? link(url) : 'null';
}
}
},
},
];
return fields.filter(({ value }) => value !== undefined && value !== null) as {
label: string;
value: string;
}[];
}
import formatFields from '../../utils/formatFields';
export function formatGraphQLBuild(build: BuildFragment): string {
const actor = getActorName(build);
@@ -117,11 +81,10 @@ export function formatGraphQLBuild(build: BuildFragment): string {
},
{
label: 'Logs',
value: link(getBuildLogsUrl(build)),
value: getBuildLogsUrl(build),
},
...formatGraphQLBuildArtifacts(build),
{
label: 'Fingerprint',
label: 'Artifact',
get value() {
switch (build.status) {
case GraphQLBuildStatus.New:
@@ -133,8 +96,8 @@ export function formatGraphQLBuild(build: BuildFragment): string {
case GraphQLBuildStatus.Errored:
return null;
case GraphQLBuildStatus.Finished: {
const hash = build.fingerprint?.hash;
return hash ? chalk.green(hash) : chalk.red('not found');
const url = build.artifacts?.buildUrl;
return url ? url : chalk.red('not found');
}
default:
return null;
@@ -26,7 +26,7 @@ import {
CommandEvent,
createAnalyticsAsync,
} from '../analytics/AnalyticsManager';
import { EnvironmentVariableEnvironment } from '../build/utils/environment';
import { EnvironmentVariableEnvironment } from '../graphql/generated';
import Log, { link } from '../log';
import SessionManager from '../user/SessionManager';
import { Client } from '../vcs/vcs';
@@ -1,5 +1,5 @@
import { Analytics } from '../../analytics/AnalyticsManager';
import { EnvironmentVariableEnvironment } from '../../build/utils/environment';
import { EnvironmentVariableEnvironment } from '../../graphql/generated';
import SessionManager from '../../user/SessionManager';
import { Client } from '../../vcs/vcs';
@@ -1,5 +1,5 @@
import { ExpoGraphqlClient } from './createGraphqlClient';
import { EnvironmentVariableEnvironment } from '../../../build/utils/environment';
import { EnvironmentVariableEnvironment } from '../../../graphql/generated';
import { EnvironmentVariablesQuery } from '../../../graphql/queries/EnvironmentVariablesQuery';
import Log from '../../../log';
+2 -1
View File
@@ -1,6 +1,6 @@
import { Flags } from '@oclif/core';
import { EnvironmentVariableEnvironment } from '../build/utils/environment';
import { EnvironmentVariableEnvironment } from '../graphql/generated';
// NOTE: not exactly true, but, provided mapToLowercase and upperCaseAsync
// are used in tandem, it saves on unnecessary typying in commands
@@ -24,6 +24,7 @@ export const EasNonInteractiveAndJsonFlags = {
export const EasEnvironmentFlagParameters = {
description: "Environment variable's environment",
parse: upperCaseAsync,
options: mapToLowercase([
EnvironmentVariableEnvironment.Development,
EnvironmentVariableEnvironment.Preview,
@@ -1,209 +0,0 @@
import { EasJsonAccessor, EasJsonUtils } from '@expo/eas-json';
import { InvalidEasJsonError, MissingEasJsonError } from '@expo/eas-json/build/errors';
import { CombinedError } from '@urql/core';
import { promises as fs } from 'fs';
import path from 'path';
import * as YAML from 'yaml';
import { getExpoApiWorkflowSchemaURL } from '../../api';
import { WorkflowRevisionMutation } from '../../graphql/mutations/WorkflowRevisionMutation';
import Log from '../../log';
import { createValidator, getReadableErrors } from '../../metadata/utils/ajv';
import { WorkflowFile } from '../../utils/workflowFile';
import { ExpoGraphqlClient } from '../context/contextUtils/createGraphqlClient';
const jobTypesWithBuildProfile = new Set(['build', 'repack']);
const buildProfileIsInterpolated = (profileName: string): boolean => {
return profileName.includes('${{') && profileName.includes('}}');
};
export async function validateWorkflowFileAsync(
workflowFileContents: { yamlConfig: string; filePath: string },
projectDir: string,
graphqlClient: ExpoGraphqlClient,
projectId: string
): Promise<void> {
const parsedYaml = parsedYamlFromWorkflowContents(workflowFileContents);
Log.debug(`Parsed workflow: ${JSON.stringify(parsedYaml, null, 2)}`);
// Check if the parsed result is empty or null
Log.debug(`Validating workflow is not empty...`);
validateWorkflowIsNotEmpty(parsedYaml);
const workflowSchema = await fetchWorkflowSchemaAsync();
// Check that all job types are valid
Log.debug(`Validating workflow job types...`);
validateWorkflowJobTypes(parsedYaml, workflowSchema);
// Check for build jobs that do not match any EAS build profiles
Log.debug(`Validating workflow build jobs...`);
await validateWorkflowBuildJobsAsync(parsedYaml, projectDir);
// Check that result passes validation against workflow schema
Log.debug(`Validating workflow structure...`);
validateWorkflowStructure(parsedYaml, workflowSchema);
// Check for other errors using the server-side validation
Log.debug(`Validating workflow on server...`);
await validateWorkflowOnServerAsync(graphqlClient, projectId, workflowFileContents);
}
export function logWorkflowValidationErrors(error: unknown): void {
if (error instanceof MissingEasJsonError) {
throw new Error(
'Workflows require a valid eas.json. Please run "eas build:configure" to create it.'
);
} else if (error instanceof InvalidEasJsonError) {
throw new Error(
'Workflows require a valid eas.json. Please fix the errors in your eas.json and try again.\n\n' +
error.message
);
} else if (error instanceof YAML.YAMLParseError) {
Log.error(`YAML syntax error: ${error.message}`);
} else if (error instanceof CombinedError) {
WorkflowFile.maybePrintWorkflowFileValidationErrors({
error,
});
throw error;
} else if (error instanceof Error) {
Log.error(`Error: ${error.message}`);
} else {
Log.error(`Unexpected error: ${String(error)}`);
}
}
function validateWorkflowIsNotEmpty(parsedYaml: any): void {
if (
parsedYaml === null ||
parsedYaml === undefined ||
(typeof parsedYaml === 'object' && Object.keys(parsedYaml).length === 0)
) {
throw new Error('YAML file is empty or contains only comments.');
}
}
async function validateWorkflowOnServerAsync(
graphqlClient: ExpoGraphqlClient,
projectId: string,
workflowFileContents: { yamlConfig: string }
): Promise<void> {
await WorkflowRevisionMutation.validateWorkflowYamlConfigAsync(graphqlClient, {
appId: projectId,
yamlConfig: workflowFileContents.yamlConfig,
});
}
async function validateWorkflowBuildJobsAsync(parsedYaml: any, projectDir: string): Promise<void> {
const jobs = jobsFromWorkflow(parsedYaml);
const buildJobs = jobs.filter(job => jobTypesWithBuildProfile.has(job.value.type));
if (buildJobs.length === 0) {
return;
}
const easJsonAccessor = EasJsonAccessor.fromProjectPath(projectDir);
const buildProfileNames = new Set(
easJsonAccessor && (await EasJsonUtils.getBuildProfileNamesAsync(easJsonAccessor))
);
const invalidBuildJobs = buildJobs.filter(
job =>
!buildProfileNames.has(job.value.params.profile) &&
// If a profile name is interpolated, we can't check if it's valid until the workflow actually runs
!buildProfileIsInterpolated(job.value.params.profile)
);
if (invalidBuildJobs.length > 0) {
const invalidBuildProfiles = new Set(invalidBuildJobs.map(job => job.value.params.profile));
throw new Error(
`The build jobs in this workflow refer to the following build profiles that are not present in your eas.json file: ${[
...invalidBuildProfiles,
].join(', ')}`
);
}
}
function validateWorkflowJobTypes(parsedYaml: any, workflowJsonSchema: any): void {
const jobs = jobsFromWorkflow(parsedYaml);
const jobTypes = jobTypesFromWorkflowSchema(workflowJsonSchema);
const invalidJobs = jobs.filter(job => job.value.type && !jobTypes.includes(job.value.type));
if (invalidJobs.length > 0) {
throw new Error(
`The following jobs have invalid types: ${invalidJobs
.map(job => job.key)
.join(', ')}. Valid types are: ${jobTypes.join(', ')}`
);
}
}
function validateWorkflowStructure(parsedYaml: any, workflowJsonSchema: any): void {
delete workflowJsonSchema['$schema'];
const ajv = createValidator();
const validate = ajv.compile(workflowJsonSchema);
const result = validate(parsedYaml);
if (!result) {
Log.debug(
JSON.stringify(
{
errors: validate.errors,
},
null,
2
)
);
const readableErrors = getReadableErrors(validate.errors ?? []);
const processedErrors = new Set<string>();
for (const err of readableErrors) {
if (err.message) {
processedErrors.add(err.message);
}
}
throw new Error([...processedErrors].join('\n'));
}
}
function parsedYamlFromWorkflowContents(workflowFileContents: {
yamlConfig: string;
}): Promise<any> {
const parsedYaml = YAML.parse(workflowFileContents.yamlConfig);
return parsedYaml;
}
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
async function fetchWorkflowSchemaAsync(): Promise<any> {
// EXPO_TESTING_WORKFLOW_SCHEMA_PATH is used only for testing against a different schema
if (process.env.EXPO_TESTING_WORKFLOW_SCHEMA_PATH) {
const schemaPath = path.resolve(process.env.EXPO_TESTING_WORKFLOW_SCHEMA_PATH);
Log.debug(`Loading workflow schema from ${schemaPath}`);
const jsonString = await fs.readFile(schemaPath, 'utf-8');
const jsonFromFile = JSON.parse(jsonString);
return jsonFromFile.data;
}
// Otherwise, we fetch from <ApiBaseUrl>/v2/workflows/schema
const schemaUrl = getExpoApiWorkflowSchemaURL();
Log.debug(`Fetching workflow schema from ${schemaUrl}`);
const response = await fetch(schemaUrl);
if (!response.ok) {
throw new Error(`Unable to fetch EAS Workflow schema, received status: ${response.status}`);
}
const jsonResponse: any = (await response.json()) as any;
return jsonResponse.data;
}
function jobsFromWorkflow(parsedYaml: any): any[] {
return Object.entries(parsedYaml?.jobs).flatMap(([key, value]: [string, any]) => {
return {
key,
value,
};
});
}
function jobTypesFromWorkflowSchema(workflowJsonSchema: any): string[] {
return workflowJsonSchema?.properties?.jobs?.additionalProperties?.anyOf.map(
(props: any) => props.properties.type.const
);
}
@@ -10,10 +10,10 @@ import Log, { learnMore } from '../../log';
import { RequestedPlatform } from '../../platform';
import { isExpoUpdatesInstalled, isUsingEASUpdate } from '../../project/projectUtils';
import { resolveWorkflowAsync } from '../../project/workflow';
import { promptAsync } from '../../prompts';
import { syncUpdatesConfigurationAsync as syncAndroidUpdatesConfigurationAsync } from '../../update/android/UpdatesModule';
import { ensureEASUpdateIsConfiguredInEasJsonAsync } from '../../update/configure';
import { syncUpdatesConfigurationAsync as syncIosUpdatesConfigurationAsync } from '../../update/ios/UpdatesModule';
import { promptPlatformAsync } from '../../utils/prompts';
export default class BuildConfigure extends EasCommand {
static override description = 'configure the project to support EAS Build';
@@ -113,7 +113,24 @@ export default class BuildConfigure extends EasCommand {
async function promptForPlatformAsync(): Promise<RequestedPlatform> {
Log.addNewLineIfNone();
return await promptPlatformAsync({
const { platform } = await promptAsync({
type: 'select',
message: 'Which platforms would you like to configure for EAS Build?',
name: 'platform',
choices: [
{
title: 'All',
value: RequestedPlatform.All,
},
{
title: 'iOS',
value: RequestedPlatform.Ios,
},
{
title: 'Android',
value: RequestedPlatform.Android,
},
],
});
return platform;
}
@@ -10,7 +10,6 @@ import { evaluateConfigWithEnvVarsAsync } from '../../build/evaluateConfigWithEn
import { ensureIosCredentialsForBuildResignAsync } from '../../build/ios/credentials';
import { prepareCredentialsToResign } from '../../build/ios/prepareJob';
import { listAndSelectBuildOnAppAsync } from '../../build/queries';
import { EnvironmentVariableEnvironment } from '../../build/utils/environment';
import { printBuildResults, printLogsUrls } from '../../build/utils/printBuildInfo';
import EasCommand from '../../commandUtils/EasCommand';
import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
@@ -23,6 +22,7 @@ import {
BuildStatus,
BuildWorkflow,
DistributionType,
EnvironmentVariableEnvironment,
IosJobOverridesInput,
ProjectArchiveSourceType,
StatuspageServiceName,
@@ -16,6 +16,7 @@ import { toggleConfirmAsync } from '../../prompts';
import { enableJsonOutput, printJsonOnlyOutput } from '../../utils/json';
export default class ChannelDelete extends EasCommand {
static override hidden = true;
static override description = 'Delete a channel';
static override args = [
@@ -5,10 +5,10 @@ import chalk from 'chalk';
import fs from 'node:fs';
import * as path from 'node:path';
import { EnvironmentVariableEnvironment } from '../../build/utils/environment';
import { getHostingDeploymentsUrl } from '../../build/utils/url';
import EasCommand from '../../commandUtils/EasCommand';
import { EASEnvironmentFlag, EasNonInteractiveAndJsonFlags } from '../../commandUtils/flags';
import { EnvironmentVariableEnvironment } from '../../graphql/generated';
import Log, { link } from '../../log';
import { ora } from '../../ora';
import { getOwnerAccountForProjectIdAsync } from '../../project/projectUtils';
@@ -1,11 +1,11 @@
import { Config } from '@oclif/core';
import { getMockAppFragment } from '../../../__tests__/commands/utils';
import { EnvironmentVariableEnvironment } from '../../../build/utils/environment';
import { ExpoGraphqlClient } from '../../../commandUtils/context/contextUtils/createGraphqlClient';
import { testProjectId } from '../../../credentials/__tests__/fixtures-constants';
import {
EnvironmentSecretType,
EnvironmentVariableEnvironment,
EnvironmentVariableScope,
EnvironmentVariableVisibility,
} from '../../../graphql/generated';
@@ -47,7 +47,6 @@ describe(EnvCreate, () => {
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
scope: EnvironmentVariableScope.Project,
type: EnvironmentSecretType.String,
}));
jest
.mocked(EnvironmentVariableMutation.createSharedVariableAsync)
@@ -57,7 +56,6 @@ describe(EnvCreate, () => {
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
scope: EnvironmentVariableScope.Shared,
type: EnvironmentSecretType.String,
}));
jest
.mocked(EnvironmentVariableMutation.updateAsync)
@@ -201,6 +199,7 @@ describe(EnvCreate, () => {
{
name: 'VarName',
value: 'VarValue',
isGlobal: true,
environments: [EnvironmentVariableEnvironment.Production],
visibility: EnvironmentVariableVisibility.Public,
type: EnvironmentSecretType.String,
@@ -325,6 +324,7 @@ describe(EnvCreate, () => {
EnvironmentVariableEnvironment.Development,
],
visibility: EnvironmentVariableVisibility.Public,
isGlobal: true,
type: EnvironmentSecretType.String,
},
testAccountId
@@ -1,7 +1,9 @@
import { Config } from '@oclif/core';
import { EnvironmentVariableEnvironment } from '../../../build/utils/environment';
import { EnvironmentVariableScope } from '../../../graphql/generated';
import {
EnvironmentVariableEnvironment,
EnvironmentVariableScope,
} from '../../../graphql/generated';
import { EnvironmentVariableMutation } from '../../../graphql/mutations/EnvironmentVariableMutation';
import { EnvironmentVariablesQuery } from '../../../graphql/queries/EnvironmentVariablesQuery';
import Log from '../../../log';
+1 -1
View File
@@ -1,10 +1,10 @@
import { Config } from '@oclif/core';
import { EnvironmentVariableEnvironment } from '../../../build/utils/environment';
import { ExpoGraphqlClient } from '../../../commandUtils/context/contextUtils/createGraphqlClient';
import { testProjectId } from '../../../credentials/__tests__/fixtures-constants';
import {
EnvironmentSecretType,
EnvironmentVariableEnvironment,
EnvironmentVariableFragment,
EnvironmentVariableScope,
EnvironmentVariableVisibility,
@@ -1,11 +1,11 @@
import { Config } from '@oclif/core';
import { getMockAppFragment } from '../../../__tests__/commands/utils';
import { EnvironmentVariableEnvironment } from '../../../build/utils/environment';
import { ExpoGraphqlClient } from '../../../commandUtils/context/contextUtils/createGraphqlClient';
import { testProjectId } from '../../../credentials/__tests__/fixtures-constants';
import {
EnvironmentSecretType,
EnvironmentVariableEnvironment,
EnvironmentVariableFragment,
EnvironmentVariableScope,
EnvironmentVariableVisibility,
@@ -2,8 +2,8 @@ import { Config } from '@oclif/core';
import chalk from 'chalk';
import { getMockAppFragment } from '../../../__tests__/commands/utils';
import { EnvironmentVariableEnvironment } from '../../../build/utils/environment';
import {
EnvironmentVariableEnvironment,
EnvironmentVariableScope,
EnvironmentVariableVisibility,
} from '../../../graphql/generated';
+2 -1
View File
@@ -3,7 +3,6 @@ import chalk from 'chalk';
import fs from 'fs-extra';
import path from 'path';
import { EnvironmentVariableEnvironment } from '../../build/utils/environment';
import EasCommand from '../../commandUtils/EasCommand';
import {
EASEnvironmentVariableScopeFlag,
@@ -14,6 +13,7 @@ import {
} from '../../commandUtils/flags';
import {
EnvironmentSecretType,
EnvironmentVariableEnvironment,
EnvironmentVariableScope,
EnvironmentVariableVisibility,
} from '../../graphql/generated';
@@ -220,6 +220,7 @@ export default class EnvCreate extends EasCommand {
value,
visibility,
environments,
isGlobal: true, // TODO: every account-wide variable is global for now so it's not user facing
type: type ?? EnvironmentSecretType.String,
},
ownerAccount.id
+1 -2
View File
@@ -2,7 +2,6 @@ import { Flags } from '@oclif/core';
import assert from 'assert';
import chalk from 'chalk';
import { EnvironmentVariableEnvironment } from '../../build/utils/environment';
import EasCommand from '../../commandUtils/EasCommand';
import {
EASEnvironmentVariableScopeFlag,
@@ -10,7 +9,7 @@ import {
EASNonInteractiveFlag,
EasEnvironmentFlagParameters,
} from '../../commandUtils/flags';
import { EnvironmentVariableScope } from '../../graphql/generated';
import { EnvironmentVariableEnvironment, EnvironmentVariableScope } from '../../graphql/generated';
import { EnvironmentVariableMutation } from '../../graphql/mutations/EnvironmentVariableMutation';
import { EnvironmentVariablesQuery } from '../../graphql/queries/EnvironmentVariablesQuery';
import Log from '../../log';
+1 -1
View File
@@ -1,10 +1,10 @@
import spawnAsync from '@expo/spawn-async';
import chalk from 'chalk';
import { EnvironmentVariableEnvironment } from '../../build/utils/environment';
import EasCommand from '../../commandUtils/EasCommand';
import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
import { EASNonInteractiveFlag } from '../../commandUtils/flags';
import { EnvironmentVariableEnvironment } from '../../graphql/generated';
import { EnvironmentVariablesQuery } from '../../graphql/queries/EnvironmentVariablesQuery';
import Log from '../../log';
import { promptVariableEnvironmentAsync } from '../../utils/prompts';
+1 -1
View File
@@ -1,7 +1,6 @@
import { Flags } from '@oclif/core';
import chalk from 'chalk';
import { EnvironmentVariableEnvironment } from '../../build/utils/environment';
import EasCommand from '../../commandUtils/EasCommand';
import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
import {
@@ -12,6 +11,7 @@ import {
EasEnvironmentFlagParameters,
} from '../../commandUtils/flags';
import {
EnvironmentVariableEnvironment,
EnvironmentVariableFragment,
EnvironmentVariableScope,
EnvironmentVariableVisibility,
+1 -2
View File
@@ -1,7 +1,6 @@
import { Flags } from '@oclif/core';
import chalk from 'chalk';
import { EnvironmentVariableEnvironment } from '../../build/utils/environment';
import EasCommand from '../../commandUtils/EasCommand';
import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
import {
@@ -10,7 +9,7 @@ import {
EASMultiEnvironmentFlag,
EASVariableFormatFlag,
} from '../../commandUtils/flags';
import { EnvironmentVariableScope } from '../../graphql/generated';
import { EnvironmentVariableEnvironment, EnvironmentVariableScope } from '../../graphql/generated';
import {
EnvironmentVariableWithFileContent,
EnvironmentVariablesQuery,
+12 -14
View File
@@ -3,16 +3,18 @@ import dotenv from 'dotenv';
import fs from 'fs-extra';
import path from 'path';
import { EnvironmentVariableEnvironment } from '../../build/utils/environment';
import EasCommand from '../../commandUtils/EasCommand';
import { EASMultiEnvironmentFlag } from '../../commandUtils/flags';
import {
CreateEnvironmentVariableInput,
EnvironmentVariableEnvironment,
EnvironmentVariableFragment,
EnvironmentVariableScope,
EnvironmentVariableVisibility,
} from '../../graphql/generated';
import { EnvironmentVariableMutation } from '../../graphql/mutations/EnvironmentVariableMutation';
import {
EnvironmentVariableMutation,
EnvironmentVariablePushInput,
} from '../../graphql/mutations/EnvironmentVariableMutation';
import { EnvironmentVariablesQuery } from '../../graphql/queries/EnvironmentVariablesQuery';
import Log from '../../log';
import { confirmAsync, promptAsync } from '../../prompts';
@@ -64,7 +66,8 @@ export default class EnvPush extends EasCommand {
});
}
const updateVariables = await this.parseEnvFileAsync(envPath, environments);
const updateVariables: Record<string, EnvironmentVariablePushInput> =
await this.parseEnvFileAsync(envPath, environments);
const variableNames = Object.keys(updateVariables);
@@ -216,16 +219,11 @@ export default class EnvPush extends EasCommand {
private async parseEnvFileAsync(
envPath: string,
environments: EnvironmentVariableEnvironment[]
): Promise<
Record<
string,
CreateEnvironmentVariableInput & { environments: EnvironmentVariableEnvironment[] }
>
> {
): Promise<Record<string, EnvironmentVariablePushInput>> {
if (!(await fs.exists(envPath))) {
throw new Error(`File ${envPath} does not exist.`);
}
const pushInput: Awaited<ReturnType<typeof this.parseEnvFileAsync>> = {};
const pushInput: Record<string, EnvironmentVariablePushInput> = {};
const variables: Record<string, string> = dotenv.parse(await fs.readFile(envPath, 'utf8'));
@@ -248,9 +246,9 @@ export default class EnvPush extends EasCommand {
name,
value,
environments,
visibility: name.startsWith('EXPO_PUBLIC_')
? EnvironmentVariableVisibility.Public
: EnvironmentVariableVisibility.Sensitive,
visibility: name.startsWith('EXPO_SENSITIVE')
? EnvironmentVariableVisibility.Sensitive
: EnvironmentVariableVisibility.Public,
};
}
+1 -1
View File
@@ -4,7 +4,6 @@ import chalk from 'chalk';
import fs from 'fs-extra';
import path from 'path';
import { EnvironmentVariableEnvironment } from '../../build/utils/environment';
import EasCommand from '../../commandUtils/EasCommand';
import {
EASEnvironmentVariableScopeFlag,
@@ -16,6 +15,7 @@ import {
} from '../../commandUtils/flags';
import {
EnvironmentSecretType,
EnvironmentVariableEnvironment,
EnvironmentVariableFragment,
EnvironmentVariableScope,
EnvironmentVariableVisibility,
@@ -4,7 +4,6 @@ import chalk from 'chalk';
import { getExpoWebsiteBaseUrl } from '../../api';
import { selectBranchOnAppAsync } from '../../branch/queries';
import { EnvironmentVariableEnvironment } from '../../build/utils/environment';
import EasCommand from '../../commandUtils/EasCommand';
import { fetchBuildsAsync, formatBuild } from '../../commandUtils/builds';
import { GetServerSideEnvironmentVariablesFn } from '../../commandUtils/context/ServerSideEnvironmentVariablesContextField';
@@ -24,6 +23,7 @@ import {
AppPlatform,
BuildFragment,
BuildStatus,
EnvironmentVariableEnvironment,
FingerprintFragment,
UpdateFragment,
} from '../../graphql/generated';
@@ -4,7 +4,6 @@ import { Flags } from '@oclif/core';
import { getExpoWebsiteBaseUrl } from '../../api';
import { evaluateConfigWithEnvVarsAsync } from '../../build/evaluateConfigWithEnvVarsAsync';
import { EnvironmentVariableEnvironment } from '../../build/utils/environment';
import EasCommand from '../../commandUtils/EasCommand';
import {
EASEnvironmentFlag,
@@ -16,7 +15,7 @@ import {
getFingerprintInfoFromLocalProjectForPlatformsAsync,
stringToAppPlatform,
} from '../../fingerprint/utils';
import { AppPlatform } from '../../graphql/generated';
import { AppPlatform, EnvironmentVariableEnvironment } from '../../graphql/generated';
import { AppQuery } from '../../graphql/queries/AppQuery';
import Log, { link } from '../../log';
import { promptAsync } from '../../prompts';
@@ -86,7 +86,7 @@ export default class MetadataPull extends EasCommand {
- Update the ${chalk.bold(relativePath)} file to prepare the app information.
- Run ${chalk.bold('eas submit')} or manually upload a new app version to the app stores.
- Once the app is uploaded, run ${chalk.bold('eas metadata:push')} to sync the store config.
- ${learnMore('https://docs.expo.dev/eas/metadata/')}`);
- ${learnMore('https://docs.expo.dev/eas-metadata/introduction/')}`);
} catch (error: any) {
handleMetadataError(error);
}
@@ -1,714 +0,0 @@
import { ExpoConfig } from '@expo/config';
import fs from 'fs-extra';
import merge from 'ts-deepmerge';
import { getEASUpdateURL } from '../../../api';
import { ExpoGraphqlClient } from '../../../commandUtils/context/contextUtils/createGraphqlClient';
import { jester, jester2 } from '../../../credentials/__tests__/fixtures-constants';
import { AppFragment, Role } from '../../../graphql/generated';
import { AppMutation } from '../../../graphql/mutations/AppMutation';
import { canAccessRepositoryUsingSshAsync, runGitCloneAsync } from '../../../onboarding/git';
import {
installDependenciesAsync,
promptForPackageManagerAsync,
} from '../../../onboarding/installDependencies';
import { runCommandAsync } from '../../../onboarding/runCommand';
import { Ora, ora } from '../../../ora';
import {
createOrModifyExpoConfigAsync,
getPrivateExpoConfigAsync,
} from '../../../project/expoConfig';
import { findProjectIdByAccountNameAndSlugNullableAsync } from '../../../project/fetchOrCreateProjectIDForWriteToConfigWithConfirmationAsync';
import { promptAsync } from '../../../prompts';
import { Actor, getActorUsername } from '../../../user/User';
import New, {
cloneTemplateAsync,
copyProjectTemplatesAsync,
createProjectAsync,
formatScriptCommand,
generateAppConfigAsync,
generateEasConfigAsync,
getAccountChoices,
initializeGitRepositoryAsync,
installProjectDependenciesAsync,
mergeReadmeAsync,
promptForTargetDirectoryAsync,
updatePackageJsonAsync,
} from '../new';
jest.mock('../../../prompts');
jest.mock('../../../onboarding/git');
jest.mock('../../../onboarding/runCommand');
jest.mock('../../../graphql/mutations/AppMutation');
jest.mock('../../../project/expoConfig');
jest.mock('../../../project/fetchOrCreateProjectIDForWriteToConfigWithConfirmationAsync');
jest.mock('../../../user/User', () => ({
getActorUsername: jest.fn(),
}));
jest.mock('../../../ora');
jest.mock('fs-extra');
jest.mock('../../../onboarding/installDependencies');
jest.mock('../../../api');
jest.mock('../../../build/utils/url');
jest.mock('../../../utils/easCli', () => ({
easCliVersion: '5.0.0',
}));
// Remove Log module mocking entirely - use the actual module
describe(New.name, () => {
let consoleLogSpy: jest.SpyInstance;
beforeEach(() => {
jest.clearAllMocks();
// Capture console.log calls
consoleLogSpy = jest.spyOn(console, 'log');
jest.mocked(fs.writeFile).mockImplementation(() => Promise.resolve());
jest.mocked(fs.readJson).mockImplementation(() => Promise.resolve({}));
jest.mocked(fs.writeJson).mockImplementation(() => Promise.resolve());
jest.mocked(fs.copy).mockImplementation(() => Promise.resolve());
jest.mocked(fs.remove).mockImplementation(() => Promise.resolve());
jest.mocked(fs.readFile).mockImplementation(() => Promise.resolve(''));
});
afterEach(() => {
consoleLogSpy.mockRestore();
});
// Helper function to get all console output as strings
const getConsoleOutput = (): string[] => {
return consoleLogSpy.mock.calls.map(call => (call.length === 0 ? '' : call.join(' ')));
};
// Helper function to check if a specific message was logged
const expectConsoleToContain = (message: string): void => {
const output = getConsoleOutput();
// strip out ANSI codes and special characters like the tick
const outputWithoutAnsi = output.map(line =>
line.replace(/\x1b\[[0-9;]*m/g, '').replace(/✔\s*/, '')
);
// throw new Error(message + '\n' + outputWithoutAnsi.join('\n'));
expect(outputWithoutAnsi.some(line => line.includes(message))).toBeTruthy();
};
// Helper function to verify prompt was called with expected message
const expectPromptToHaveMessage = (expectedMessage: string): void => {
expect(promptAsync).toHaveBeenCalledWith(
expect.objectContaining({
message: expectedMessage,
})
);
};
// Helper function to simulate user input via prompt
const mockUserInput = (inputValue: any): void => {
jest.mocked(promptAsync).mockResolvedValue(inputValue);
};
describe('helper functions', () => {
describe('promptForTargetDirectoryAsync', () => {
it('should prompt for target directory', async () => {
const promptedDirectory = '/test/prompted-project';
mockUserInput({ targetProjectDir: promptedDirectory });
const result = await promptForTargetDirectoryAsync();
expectConsoleToContain(
`🚚 Let's start by cloning the default Expo template project from GitHub and installing dependencies.`
);
expectPromptToHaveMessage('Where would you like to create your new project directory?');
expect(result).toBe(promptedDirectory);
});
it('should handle the target directory from args', async () => {
const providedDirectory = '/test/provided-project';
const result = await promptForTargetDirectoryAsync(providedDirectory);
expectConsoleToContain(
`🚚 Let's start by cloning the default Expo template project from GitHub and installing dependencies.`
);
expect(promptAsync).not.toHaveBeenCalled();
expect(result).toBe(providedDirectory);
});
});
describe('cloneTemplateAsync', () => {
it('should clone the template project with ssh', async () => {
const targetProjectDir = '/test/target-project';
const finalTargetProjectDir = '/test/final-target-project';
jest.mocked(canAccessRepositoryUsingSshAsync).mockResolvedValue(true);
jest.mocked(runGitCloneAsync).mockResolvedValue({
targetProjectDir: finalTargetProjectDir,
});
const result = await cloneTemplateAsync(targetProjectDir);
expectConsoleToContain(`📂 Cloning the project to ${targetProjectDir}`);
expectConsoleToContain('We detected that ssh is your preferred git clone method');
expect(runGitCloneAsync).toHaveBeenCalledWith({
githubUsername: 'expo',
githubRepositoryName: 'expo-template-default',
targetProjectDir,
cloneMethod: 'ssh',
});
expect(result).toBe(finalTargetProjectDir);
});
it('should clone the template project with https', async () => {
const targetProjectDir = '/test/target-project';
const finalTargetProjectDir = '/test/final-target-project';
jest.mocked(canAccessRepositoryUsingSshAsync).mockResolvedValue(false);
jest.mocked(runGitCloneAsync).mockResolvedValue({
targetProjectDir: finalTargetProjectDir,
});
const result = await cloneTemplateAsync(targetProjectDir);
expectConsoleToContain(`📂 Cloning the project to ${targetProjectDir}`);
expectConsoleToContain('We detected that https is your preferred git clone method');
expect(runGitCloneAsync).toHaveBeenCalledWith({
githubUsername: 'expo',
githubRepositoryName: 'expo-template-default',
targetProjectDir,
cloneMethod: 'https',
});
expect(result).toBe(finalTargetProjectDir);
});
});
describe('installProjectDependenciesAsync', () => {
it('should install the project dependencies', async () => {
const projectDir = '/test/project-directory';
jest.mocked(promptForPackageManagerAsync).mockResolvedValue('npm');
jest.mocked(installDependenciesAsync).mockResolvedValue();
jest.mocked(runCommandAsync).mockResolvedValue();
const packageManager = await installProjectDependenciesAsync(projectDir);
expect(packageManager).toBe('npm');
expect(promptForPackageManagerAsync).toHaveBeenCalled();
expect(installDependenciesAsync).toHaveBeenCalledWith({
projectDir,
packageManager: 'npm',
});
expect(runCommandAsync).toHaveBeenCalledWith({
cwd: projectDir,
command: 'npx',
args: ['expo', 'install', 'expo-updates'],
});
expect(runCommandAsync).toHaveBeenCalledWith({
cwd: projectDir,
command: 'npx',
args: ['expo', 'install', '@expo/metro-runtime'],
});
});
});
describe('getAccountChoices', () => {
it('should return mapped account choices', () => {
// Use jester fixture which has multiple accounts with different permissions
const namesWithSufficientPermissions = new Set(['jester']); // Only personal account has permissions
const result = getAccountChoices(jester, namesWithSufficientPermissions);
expect(result).toEqual([
{
title: 'jester (personal account)',
value: { name: 'jester' },
},
{
title: 'other',
value: { name: 'other' },
disabled: true,
description:
'You do not have the required permissions to create projects on this account.',
},
]);
});
});
describe('createProjectAsync', () => {
const mockGraphqlClient = {} as ExpoGraphqlClient;
const projectDir = '/test/project-dir';
const mockProjectId = 'test-project-id';
beforeEach(() => {
// use single-account jester for most of the tests
jest.mocked(getActorUsername).mockReturnValue('jester2');
jest.mocked(getPrivateExpoConfigAsync).mockResolvedValue({
name: 'test-app',
slug: 'test-app',
extra: {},
} as ExpoConfig);
jest.mocked(createOrModifyExpoConfigAsync).mockResolvedValue({
type: 'success' as const,
message: 'Config updated',
config: {
name: 'test-app',
slug: 'test-app',
extra: { eas: { projectId: 'test-project-id' } },
} as ExpoConfig,
});
const mockSpinner: Partial<Ora> = {
start: jest.fn().mockReturnThis(),
succeed: jest.fn().mockReturnThis(),
fail: jest.fn().mockReturnThis(),
};
jest.mocked(ora).mockReturnValue(mockSpinner as Ora);
});
it('should create a project', async () => {
const mockActor = jester2 as Actor;
jest.mocked(findProjectIdByAccountNameAndSlugNullableAsync).mockResolvedValue(null);
jest.mocked(AppMutation.createAppAsync).mockResolvedValue(mockProjectId);
const result = await createProjectAsync(mockGraphqlClient, mockActor, projectDir);
expect(findProjectIdByAccountNameAndSlugNullableAsync).toHaveBeenCalledWith(
mockGraphqlClient,
'jester2',
'jester2-app'
);
expect(AppMutation.createAppAsync).toHaveBeenCalledWith(mockGraphqlClient, {
accountId: 'jester2-account-id',
projectName: 'jester2-app',
});
expect(createOrModifyExpoConfigAsync).toHaveBeenCalledWith(
projectDir,
{
extra: { eas: { projectId: mockProjectId } },
},
{ skipSDKVersionRequirement: true }
);
expect(result).toBe(mockProjectId);
});
it('should create a project when there are multiple accounts', async () => {
// Use jester fixture which has multiple accounts
const mockActor = jester;
jest.mocked(getActorUsername).mockReturnValue('jester');
jest.mocked(promptAsync).mockResolvedValue({
account: { name: 'jester' },
});
jest.mocked(findProjectIdByAccountNameAndSlugNullableAsync).mockResolvedValue(null);
jest.mocked(AppMutation.createAppAsync).mockResolvedValue(mockProjectId);
const result = await createProjectAsync(mockGraphqlClient, mockActor, projectDir);
expect(promptAsync).toHaveBeenCalledWith({
type: 'select',
name: 'account',
message: 'Which account should own this project?',
choices: expect.any(Array),
});
expect(findProjectIdByAccountNameAndSlugNullableAsync).toHaveBeenCalledWith(
mockGraphqlClient,
'jester',
'jester-app'
);
expect(AppMutation.createAppAsync).toHaveBeenCalledWith(mockGraphqlClient, {
accountId: 'jester-account-id',
projectName: 'jester-app',
});
expect(result).toBe(mockProjectId);
});
it('should throw when the project already exists', async () => {
const mockActor = jester2 as Actor;
const existingProjectId = 'existing-project-id';
jest
.mocked(findProjectIdByAccountNameAndSlugNullableAsync)
.mockResolvedValue(existingProjectId);
await expect(createProjectAsync(mockGraphqlClient, mockActor, projectDir)).rejects.toThrow(
`Existing project found: @jester2/jester2-app (ID: ${existingProjectId}). Project ID configuration canceled. Re-run the command to select a different account/project.`
);
expect(AppMutation.createAppAsync).not.toHaveBeenCalled();
});
it('should throw when the user does not have permission to create projects on account', async () => {
// Create a custom actor with ViewOnly permissions for this test
const mockActor = merge(jester2, {
accounts: [{ users: [{ actor: { id: 'view-only-jester' }, role: Role.ViewOnly }] }],
}) as Actor;
jest.mocked(getActorUsername).mockReturnValue('view-only-jester');
jest.mocked(findProjectIdByAccountNameAndSlugNullableAsync).mockResolvedValue(null);
await expect(createProjectAsync(mockGraphqlClient, mockActor, projectDir)).rejects.toThrow(
`You don't have permission to create a new project on the jester account and no matching project already exists on the account.`
);
expect(AppMutation.createAppAsync).not.toHaveBeenCalled();
});
});
describe('generateAppConfigAsync', () => {
const projectDir = '/test/project-dir';
const mockUpdateUrl = 'https://u.expo.dev/test-project-id';
const createMockApp = (overrides: Partial<AppFragment> = {}): AppFragment => ({
id: 'test-project-id',
name: 'Test App',
fullName: '@testowner/test-app',
slug: 'test-app',
ownerAccount: {
id: 'testowner-account-id',
name: 'testowner',
users: [],
},
...overrides,
});
beforeEach(() => {
jest.mocked(getEASUpdateURL).mockReturnValue(mockUpdateUrl);
jest.mocked(fs.readJson).mockResolvedValue({
expo: {} as ExpoConfig,
});
});
it('should generate the app config', async () => {
const mockApp = createMockApp();
jest.mocked(fs.readJson).mockResolvedValue({
expo: {
name: 'value-to-override',
slug: 'value-to-override',
icon: 'value-to-keep',
} as ExpoConfig,
});
await generateAppConfigAsync(projectDir, mockApp);
expect(getEASUpdateURL).toHaveBeenCalledWith('test-project-id', null);
const expectedConfig = {
expo: {
name: 'Test App',
slug: 'test-app',
scheme: 'TestApp',
icon: 'value-to-keep',
extra: {
eas: {
projectId: 'test-project-id',
},
},
owner: 'testowner',
updates: {
url: mockUpdateUrl,
},
runtimeVersion: {
policy: 'appVersion',
},
ios: {
bundleIdentifier: 'com.testowner.testapp',
},
android: {
package: 'com.testowner.testapp',
},
},
};
expect(fs.writeJson).toHaveBeenCalledWith(`${projectDir}/app.json`, expectedConfig, {
spaces: 2,
});
expectConsoleToContain('Generated app.json');
});
it('should handle invalid characters in the bundle identifier', async () => {
const mockApp = createMockApp({
slug: 'test-app-with-dashes',
ownerAccount: {
id: 'test-owner-account-id',
name: 'test-owner',
users: [],
},
});
await generateAppConfigAsync(projectDir, mockApp);
expect(fs.writeJson).toHaveBeenCalledWith(
`${projectDir}/app.json`,
expect.objectContaining({
expo: expect.objectContaining({
ios: expect.objectContaining({
bundleIdentifier: 'com.testowner.testappwithdashes',
}),
}),
}),
{ spaces: 2 }
);
});
it('should handle invalid characters in the owner account name', async () => {
const mockApp = createMockApp({
slug: 'testapp',
ownerAccount: {
id: 'test-owner-123-account-id',
name: 'test-owner-123',
users: [],
},
});
await generateAppConfigAsync(projectDir, mockApp);
expect(fs.writeJson).toHaveBeenCalledWith(
`${projectDir}/app.json`,
expect.objectContaining({
expo: expect.objectContaining({
ios: expect.objectContaining({
bundleIdentifier: 'com.testowner123.testapp',
}),
}),
}),
{ spaces: 2 }
);
});
it('should handle invalid characters in the slug', async () => {
const mockApp = createMockApp({
slug: 'test@app#with$symbols',
fullName: '@testowner/test@app#with$symbols',
});
await generateAppConfigAsync(projectDir, mockApp);
expect(fs.writeJson).toHaveBeenCalledWith(
`${projectDir}/app.json`,
expect.objectContaining({
expo: expect.objectContaining({
ios: expect.objectContaining({
bundleIdentifier: 'com.testowner.testappwithsymbols',
}),
}),
}),
{ spaces: 2 }
);
});
});
describe('generateEasConfigAsync', () => {
const projectDir = '/test/project-dir';
it('should generate the eas config', async () => {
const expectedEasConfig = {
cli: {
version: '>= 5.0.0',
appVersionSource: 'remote',
},
build: {
development: {
developmentClient: true,
distribution: 'internal',
android: { image: 'latest' },
ios: { image: 'latest' },
},
'development-simulator': {
extends: 'development',
ios: { simulator: true },
},
preview: {
distribution: 'internal',
channel: 'main',
android: { image: 'latest' },
ios: { image: 'latest' },
},
production: {
channel: 'production',
autoIncrement: true,
android: { image: 'latest' },
ios: { image: 'latest' },
},
},
submit: {
production: {},
},
};
await generateEasConfigAsync(projectDir);
expect(fs.writeJson).toHaveBeenCalledWith(`${projectDir}/eas.json`, expectedEasConfig, {
spaces: 2,
});
expectConsoleToContain('Generated eas.json');
});
});
describe('updatePackageJsonAsync', () => {
it('should update the package.json', async () => {
jest.mocked(fs.readJson).mockResolvedValue({
name: 'test-app',
version: '1.0.0',
});
const projectDir = '/test/project-dir';
await updatePackageJsonAsync(projectDir);
const expectedPackageJson = {
name: 'test-app',
version: '1.0.0',
scripts: {
preview: 'npx eas-cli@latest workflow:run publish-preview-update.yml',
'development-builds': 'npx eas-cli@latest workflow:run create-development-builds.yml',
deploy: 'npx eas-cli@latest workflow:run deploy-to-production.yml',
},
};
expect(fs.writeJson).toHaveBeenCalledWith(
`${projectDir}/package.json`,
expectedPackageJson,
{ spaces: 2 }
);
expectConsoleToContain('Updated package.json with scripts');
});
});
describe('copyProjectTemplatesAsync', () => {
it('should copy the project templates', async () => {
const projectDir = '/test/project-dir';
await copyProjectTemplatesAsync(projectDir);
expect(fs.copy).toHaveBeenCalledWith(
expect.stringContaining('templates/.eas/workflows'),
expect.stringContaining('.eas/workflows'),
{ errorOnExist: false, overwrite: true }
);
expectConsoleToContain('Created EAS workflow files');
});
});
describe('mergeReadmeAsync', () => {
const projectDir = '/test/project-dir';
it('should merge readme when target section is found', async () => {
const existingReadme = `# My App
This is my app.
## Get a fresh project
Some content here.`;
const readmeAdditions = `## Workflows
This project uses EAS Workflows.`;
(jest.mocked(fs.readFile) as jest.Mock).mockResolvedValueOnce(readmeAdditions);
(jest.mocked(fs.readFile) as jest.Mock).mockResolvedValueOnce(existingReadme);
await mergeReadmeAsync(projectDir);
const expectedMergedReadme = `# My App
This is my app.
## Workflows
This project uses EAS Workflows.
## Get a fresh project
Some content here.`;
expect(fs.writeFile).toHaveBeenCalledWith(`${projectDir}/README.md`, expectedMergedReadme);
expectConsoleToContain('Updated README.md with EAS configuration details');
});
it('should append readme when target section is not found', async () => {
const existingReadme = `# My App
This is my app.`;
const readmeAdditions = `## Workflows
This project uses EAS Workflows.`;
(jest.mocked(fs.readFile) as jest.Mock).mockResolvedValueOnce(readmeAdditions);
(jest.mocked(fs.readFile) as jest.Mock).mockResolvedValueOnce(existingReadme);
await mergeReadmeAsync(projectDir);
const expectedMergedReadme = `# My App
This is my app.
## Workflows
This project uses EAS Workflows.
`;
expect(fs.writeFile).toHaveBeenCalledWith(`${projectDir}/README.md`, expectedMergedReadme);
expectConsoleToContain('Updated README.md with EAS configuration details');
});
});
describe('initializeGitRepositoryAsync', () => {
it('should initialize git repository', async () => {
const projectDir = '/test/project-dir';
await initializeGitRepositoryAsync(projectDir);
expect(fs.remove).toHaveBeenCalledWith(`${projectDir}/.git`);
expect(runCommandAsync).toHaveBeenCalledWith({
command: 'git',
args: ['init'],
cwd: projectDir,
});
expect(runCommandAsync).toHaveBeenCalledWith({
command: 'git',
args: ['add', '.'],
cwd: projectDir,
});
expect(runCommandAsync).toHaveBeenCalledWith({
command: 'git',
args: ['commit', '-m', 'Initial commit'],
cwd: projectDir,
});
});
});
describe('formatScriptCommand', () => {
it('should format script commands for package managers', () => {
expect(formatScriptCommand('start', 'npm')).toBe('npm run start');
expect(formatScriptCommand('start', 'yarn')).toBe('yarn start');
expect(formatScriptCommand('start', 'pnpm')).toBe('pnpm start');
});
});
});
});
@@ -1,472 +0,0 @@
import { ExpoConfig } from '@expo/config';
import { AppVersionSource, EasJson } from '@expo/eas-json';
import chalk from 'chalk';
import fs from 'fs-extra';
import nullthrows from 'nullthrows';
import path from 'path';
import merge from 'ts-deepmerge';
import { getEASUpdateURL } from '../../api';
import { getProjectDashboardUrl } from '../../build/utils/url';
import EasCommand from '../../commandUtils/EasCommand';
import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
import { AppFragment, Role } from '../../graphql/generated';
import { AppMutation } from '../../graphql/mutations/AppMutation';
import { AppQuery } from '../../graphql/queries/AppQuery';
import Log, { learnMore, link } from '../../log';
import { canAccessRepositoryUsingSshAsync, runGitCloneAsync } from '../../onboarding/git';
import {
PackageManager,
installDependenciesAsync,
promptForPackageManagerAsync,
} from '../../onboarding/installDependencies';
import { runCommandAsync } from '../../onboarding/runCommand';
import { ora } from '../../ora';
import { createOrModifyExpoConfigAsync, getPrivateExpoConfigAsync } from '../../project/expoConfig';
import { findProjectIdByAccountNameAndSlugNullableAsync } from '../../project/fetchOrCreateProjectIDForWriteToConfigWithConfirmationAsync';
import { Choice, promptAsync } from '../../prompts';
import { Actor, getActorUsername } from '../../user/User';
import { easCliVersion } from '../../utils/easCli';
export async function promptForTargetDirectoryAsync(
targetProjectDirFromArgs?: string
): Promise<string> {
Log.log(
`🚚 Let's start by cloning the default Expo template project from GitHub and installing dependencies.`
);
Log.newLine();
if (targetProjectDirFromArgs) {
return targetProjectDirFromArgs;
}
const result = await promptAsync({
type: 'text',
name: 'targetProjectDir',
message: 'Where would you like to create your new project directory?',
initial: path.join(process.cwd(), 'new-expo-project'),
});
return result.targetProjectDir;
}
export async function cloneTemplateAsync(targetProjectDir: string): Promise<string> {
const githubUsername = 'expo';
const githubRepositoryName = 'expo-template-default';
Log.log(`📂 Cloning the project to ${targetProjectDir}`);
Log.newLine();
const cloneMethod = (await canAccessRepositoryUsingSshAsync({
githubUsername,
githubRepositoryName,
}))
? 'ssh'
: 'https';
Log.log(chalk.dim(`We detected that ${cloneMethod} is your preferred git clone method`));
Log.newLine();
const { targetProjectDir: finalTargetProjectDirectory } = await runGitCloneAsync({
githubUsername,
githubRepositoryName,
targetProjectDir,
cloneMethod,
});
return finalTargetProjectDirectory;
}
export async function installProjectDependenciesAsync(projectDir: string): Promise<PackageManager> {
const packageManager = await promptForPackageManagerAsync();
await installDependenciesAsync({
projectDir,
packageManager,
});
const dependencies = ['expo-updates', '@expo/metro-runtime'];
for (const dependency of dependencies) {
await runCommandAsync({
cwd: projectDir,
command: 'npx',
args: ['expo', 'install', dependency],
});
}
return packageManager;
}
export function getAccountChoices(
actor: Actor,
namesWithSufficientPermissions: Set<string>
): Choice[] {
const sortedAccounts = actor.accounts.sort((a, _b) =>
actor.__typename === 'User' ? (a.name === actor.username ? -1 : 1) : 0
);
return sortedAccounts.map(account => {
const isPersonalAccount = actor.__typename === 'User' && account.name === actor.username;
const accountDisplayName = isPersonalAccount
? `${account.name} (personal account)`
: account.name;
const disabled = !namesWithSufficientPermissions.has(account.name);
return {
title: accountDisplayName,
value: { name: account.name },
...(disabled && {
disabled: true,
description: 'You do not have the required permissions to create projects on this account.',
}),
};
});
}
export async function createProjectAsync(
graphqlClient: ExpoGraphqlClient,
actor: Actor,
projectDir: string
): Promise<string> {
const allAccounts = actor.accounts;
const accountNamesWhereUserHasSufficientPermissionsToCreateApp = new Set(
allAccounts
.filter(a => a.users.find(it => it.actor.id === actor.id)?.role !== Role.ViewOnly)
.map(it => it.name)
);
let accountName = allAccounts[0].name;
if (allAccounts.length > 1) {
const choices = getAccountChoices(
actor,
accountNamesWhereUserHasSufficientPermissionsToCreateApp
);
accountName = (
await promptAsync({
type: 'select',
name: 'account',
message: 'Which account should own this project?',
choices,
})
).account.name;
}
const projectName = getActorUsername(actor) + '-app';
const projectFullName = `@${accountName}/${projectName}`;
const existingProjectIdOnServer = await findProjectIdByAccountNameAndSlugNullableAsync(
graphqlClient,
accountName,
projectName
);
if (existingProjectIdOnServer) {
throw new Error(
`Existing project found: ${projectFullName} (ID: ${existingProjectIdOnServer}). Project ID configuration canceled. Re-run the command to select a different account/project.`
);
}
if (!accountNamesWhereUserHasSufficientPermissionsToCreateApp.has(accountName)) {
throw new Error(
`You don't have permission to create a new project on the ${accountName} account and no matching project already exists on the account.`
);
}
const projectDashboardUrl = getProjectDashboardUrl(accountName, projectName);
const projectLink = link(projectDashboardUrl, { text: projectFullName });
const account = nullthrows(allAccounts.find(a => a.name === accountName));
const spinner = ora(`Creating ${chalk.bold(projectFullName)}`).start();
let projectId: string;
try {
projectId = await AppMutation.createAppAsync(graphqlClient, {
accountId: account.id,
projectName,
});
spinner.succeed(`Created ${chalk.bold(projectLink)}`);
} catch (err) {
spinner.fail();
throw err;
}
const exp = await getPrivateExpoConfigAsync(projectDir, { skipPlugins: true });
await createOrModifyExpoConfigAsync(
projectDir,
{
extra: { ...exp.extra, eas: { ...exp.extra?.eas, projectId } },
},
{ skipSDKVersionRequirement: true }
);
Log.withTick(`Project successfully linked (ID: ${chalk.bold(projectId)}) (modified app.json)`);
return projectId;
}
export function stripInvalidCharactersForBundleIdentifier(string: string): string {
return string.replaceAll(/[^A-Za-z0-9]/g, '');
}
export async function generateConfigFilesAsync(
projectDir: string,
app: AppFragment
): Promise<void> {
await generateAppConfigAsync(projectDir, app);
await generateEasConfigAsync(projectDir);
await updatePackageJsonAsync(projectDir);
await copyProjectTemplatesAsync(projectDir);
await mergeReadmeAsync(projectDir);
}
export async function generateAppConfigAsync(projectDir: string, app: AppFragment): Promise<void> {
// Android package name requires each component to start with a lowercase letter.
const isUsernameValidSegment = /^[^a-z]/.test(app.ownerAccount.name);
const userPrefix = isUsernameValidSegment ? 'user' : '';
const isSlugValidSegment = /^[^a-z]/.test(app.slug);
const slugPrefix = isSlugValidSegment ? 'app' : '';
const bundleIdentifier = `com.${userPrefix}${stripInvalidCharactersForBundleIdentifier(
app.ownerAccount.name
)}.${slugPrefix}${stripInvalidCharactersForBundleIdentifier(app.slug)}`;
const updateUrl = getEASUpdateURL(app.id, /* manifestHostOverride */ null);
const { expo: baseExpoConfig } = await fs.readJson(path.join(projectDir, 'app.json'));
const expoConfig: ExpoConfig = {
name: app.name ?? app.slug,
slug: app.slug,
scheme: stripInvalidCharactersForBundleIdentifier(app.name ?? app.slug),
extra: {
eas: {
projectId: app.id,
},
},
owner: app.ownerAccount.name,
updates: {
url: updateUrl,
},
runtimeVersion: {
policy: 'appVersion',
},
ios: {
bundleIdentifier,
},
android: {
package: bundleIdentifier,
},
};
const mergedConfig = merge(baseExpoConfig, expoConfig);
const appJsonPath = path.join(projectDir, 'app.json');
await fs.writeJson(appJsonPath, { expo: mergedConfig }, { spaces: 2 });
Log.withTick(
`Generated ${chalk.bold('app.json')}. ${learnMore(
'https://docs.expo.dev/versions/latest/config/app/'
)}`
);
Log.log();
}
export async function generateEasConfigAsync(projectDir: string): Promise<void> {
const easBuildGitHubConfig = {
android: {
image: 'latest',
},
ios: {
image: 'latest',
},
};
const easJson: EasJson = {
cli: {
version: `>= ${easCliVersion}`,
appVersionSource: AppVersionSource.REMOTE,
},
build: {
development: {
developmentClient: true,
distribution: 'internal',
...easBuildGitHubConfig,
},
'development-simulator': {
extends: 'development',
ios: {
simulator: true,
},
},
preview: {
distribution: 'internal',
channel: 'main',
...easBuildGitHubConfig,
},
production: {
channel: 'production',
autoIncrement: true,
...easBuildGitHubConfig,
},
},
submit: {
production: {},
},
};
const easJsonPath = path.join(projectDir, 'eas.json');
await fs.writeJson(easJsonPath, easJson, { spaces: 2 });
Log.withTick(
`Generated ${chalk.bold('eas.json')}. ${learnMore(
'https://docs.expo.dev/build-reference/eas-json/'
)}`
);
Log.log();
}
export async function updatePackageJsonAsync(projectDir: string): Promise<void> {
const packageJsonPath = path.join(projectDir, 'package.json');
const packageJson = await fs.readJson(packageJsonPath);
if (!packageJson.scripts) {
packageJson.scripts = {};
}
packageJson.scripts.preview = 'npx eas-cli@latest workflow:run publish-preview-update.yml';
packageJson.scripts['development-builds'] =
'npx eas-cli@latest workflow:run create-development-builds.yml';
packageJson.scripts.deploy = 'npx eas-cli@latest workflow:run deploy-to-production.yml';
await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });
Log.withTick('Updated package.json with scripts');
Log.log();
}
export async function copyProjectTemplatesAsync(projectDir: string): Promise<void> {
const templatesSourceDir = path.join(__dirname, 'templates', '.eas', 'workflows');
const easWorkflowsTargetDir = path.join(projectDir, '.eas', 'workflows');
await fs.copy(templatesSourceDir, easWorkflowsTargetDir, {
overwrite: true,
errorOnExist: false,
});
Log.withTick('Created EAS workflow files');
Log.log();
}
export async function mergeReadmeAsync(projectDir: string): Promise<void> {
const readmeTemplatePath = path.join(__dirname, 'templates', 'readme-additions.md');
const projectReadmePath = path.join(projectDir, 'README.md');
const readmeAdditions = await fs.readFile(readmeTemplatePath, 'utf8');
const existingReadme = await fs.readFile(projectReadmePath, 'utf8');
const targetSection = '## Get a fresh project';
const sectionIndex = existingReadme.indexOf(targetSection);
let mergedReadme: string;
if (sectionIndex !== -1) {
// Insert before "## Get a fresh project" section
const beforeSection = existingReadme.substring(0, sectionIndex).trim();
const afterSection = existingReadme.substring(sectionIndex);
mergedReadme = beforeSection + '\n\n' + readmeAdditions.trim() + '\n\n' + afterSection;
} else {
// Append to the end if section doesn't exist
mergedReadme = existingReadme.trim() + '\n\n' + readmeAdditions.trim() + '\n';
}
await fs.writeFile(projectReadmePath, mergedReadme);
Log.withTick('Updated README.md with EAS configuration details');
Log.log();
}
export async function initializeGitRepositoryAsync(projectDir: string): Promise<void> {
await fs.remove(path.join(projectDir, '.git'));
const commands = [['init'], ['add', '.'], ['commit', '-m', 'Initial commit']];
for (const args of commands) {
await runCommandAsync({
cwd: projectDir,
command: 'git',
args,
});
Log.log();
}
}
export const formatScriptCommand = (script: string, packageManager: PackageManager): string => {
if (packageManager === 'npm') {
return `npm run ${script}`;
}
return `${packageManager} ${script}`;
};
export default class New extends EasCommand {
static override aliases = ['new'];
static override description = "create a new project set up with Expo's services.";
static override flags = {};
static override hidden = true;
static override args = [{ name: 'TARGET_PROJECT_DIRECTORY' }];
static override contextDefinition = {
...this.ContextOptions.LoggedIn,
};
async runAsync(): Promise<void> {
const { args } = await this.parse(New);
const {
loggedIn: { actor, graphqlClient },
} = await this.getContextAsync(New, { nonInteractive: false });
if (actor.__typename === 'Robot') {
throw new Error(
'This command is not available for robot users. Make sure you are not using a robot token and try again.'
);
}
Log.warn(
'This command is not yet implemented. It will create a new project, but it will not be fully configured.'
);
Log.log(`👋 Welcome to Expo, ${actor.username}!`);
Log.newLine();
const targetProjectDirectory = await promptForTargetDirectoryAsync(
args.TARGET_PROJECT_DIRECTORY
);
const projectDirectory = await cloneTemplateAsync(targetProjectDirectory);
const packageManager = await installProjectDependenciesAsync(projectDirectory);
const projectId = await createProjectAsync(graphqlClient, actor, projectDirectory);
const app = await AppQuery.byIdAsync(graphqlClient, projectId);
await generateConfigFilesAsync(projectDirectory, app);
await initializeGitRepositoryAsync(projectDirectory);
Log.log('🎉 We finished creating your new project.');
Log.log('Next steps:');
Log.withInfo(`Run \`cd ${projectDirectory}\` to navigate to your project.`);
Log.withInfo(
`Run \`${formatScriptCommand(
'preview',
packageManager
)}\` to create a preview build on EAS. ${learnMore(
'https://docs.expo.dev/eas/workflows/examples/publish-preview-update/'
)}`
);
Log.withInfo(
`Run \`${formatScriptCommand(
'start',
packageManager
)}\` to start developing locally. ${learnMore(
'https://docs.expo.dev/get-started/start-developing/'
)}`
);
Log.withInfo(`See the README.md for more information about your project.`);
Log.newLine();
}
}
@@ -152,7 +152,7 @@ export default class Onboarding extends EasCommand {
}))
? 'ssh'
: 'https';
Log.log(chalk.dim(`We detected that ${cloneMethod} is your preferred git clone method`));
Log.log(chalk.dim(`We detected that ${cloneMethod} is your preffered git clone method`));
Log.log();
const { targetProjectDir: finalTargetProjectDirectory } = await runGitCloneAsync({
@@ -1,21 +0,0 @@
name: Create development builds
jobs:
android_development_build:
name: Build Android
type: build
params:
platform: android
profile: development
ios_device_development_build:
name: Build iOS device
type: build
params:
platform: ios
profile: development
ios_simulator_development_build:
name: Build iOS simulator
type: build
params:
platform: ios
profile: development-simulator
@@ -1,68 +0,0 @@
name: Deploy to production
on:
push:
branches: ['main']
jobs:
fingerprint:
name: Fingerprint
type: fingerprint
get_android_build:
name: Check for existing android build
needs: [fingerprint]
type: get-build
params:
fingerprint_hash: ${{ needs.fingerprint.outputs.android_fingerprint_hash }}
profile: production
get_ios_build:
name: Check for existing ios build
needs: [fingerprint]
type: get-build
params:
fingerprint_hash: ${{ needs.fingerprint.outputs.ios_fingerprint_hash }}
profile: production
build_android:
name: Build Android
needs: [get_android_build]
if: ${{ !needs.get_android_build.outputs.build_id }}
type: build
params:
platform: android
profile: production
build_ios:
name: Build iOS
needs: [get_ios_build]
if: ${{ !needs.get_ios_build.outputs.build_id }}
type: build
params:
platform: ios
profile: production
submit_android_build:
name: Submit Android Build
needs: [build_android]
type: submit
params:
build_id: ${{ needs.build_android.outputs.build_id }}
submit_ios_build:
name: Submit iOS Build
needs: [build_ios]
type: submit
params:
build_id: ${{ needs.build_ios.outputs.build_id }}
publish_android_update:
name: Publish Android update
needs: [get_android_build]
if: ${{ needs.get_android_build.outputs.build_id }}
type: update
params:
branch: production
platform: android
publish_ios_update:
name: Publish iOS update
needs: [get_ios_build]
if: ${{ needs.get_ios_build.outputs.build_id }}
type: update
params:
branch: production
platform: ios
@@ -1,12 +0,0 @@
name: Publish preview update
on:
push:
branches: ['*']
jobs:
publish_preview_update:
name: Publish preview update
type: update
params:
branch: ${{ github.ref_name || 'test' }}
@@ -1,19 +0,0 @@
## Workflows
This project is configured to use [EAS Workflows](https://docs.expo.dev/eas/workflows/get-started/) to automate some development and release processes. These commands are set up in [`package.json`](./package.json) and can be run using NPM scripts in your terminal.
### Previews
Run `npm run preview` to [publish a preview update](https://docs.expo.dev/eas/workflows/examples/publish-preview-update/) of your project, which can be viewed in Expo Go or in a development build.
### Development Builds
Run `npm run development-builds` to [create a development build](https://docs.expo.dev/eas/workflows/examples/create-development-builds/). Note - you'll need to follow the [Prerequisites](https://docs.expo.dev/eas/workflows/examples/create-development-builds/#prerequisites) to ensure you have the correct emulator setup on your machine.
### Production Deployments
Run `npm run deploy` to [deploy to production](https://docs.expo.dev/eas/workflows/examples/deploy-to-production/). Note - you'll need to follow the [Prerequisites](https://docs.expo.dev/eas/workflows/examples/deploy-to-production/#prerequisites) to ensure you're set up to submit to the Apple and Google stores.
## Hosting
Expo offers hosting for websites and API functions via EAS Hosting. See the [Getting Started](https://docs.expo.dev/eas/hosting/get-started/) guide to learn more.
@@ -10,6 +10,7 @@ import {
AndroidSubmissionConfigInput,
IosSubmissionConfigInput,
SubmissionAndroidReleaseStatus,
SubmissionAndroidTrack,
} from '../../graphql/generated';
import { AppStoreConnectApiKeyQuery } from '../../graphql/queries/AppStoreConnectApiKeyQuery';
import { GoogleServiceAccountKeyQuery } from '../../graphql/queries/GoogleServiceAccountKeyQuery';
@@ -140,11 +141,12 @@ export default class SubmitInternal extends EasCommand {
graphqlClient,
})
);
const track = graphQlTrackToConfigTrack[androidConfig.track];
const configInput: z.input<typeof SubmissionConfig.Android.SchemaZ> = {
changesNotSentForReview,
googleServiceAccountKeyJson,
track: androidConfig.track,
track,
...(releaseStatus === SubmissionConfig.Android.ReleaseStatus.IN_PROGRESS
? {
releaseStatus: SubmissionConfig.Android.ReleaseStatus.IN_PROGRESS,
@@ -215,3 +217,10 @@ const graphQlReleaseStatusToConfigReleaseStatus = {
[SubmissionAndroidReleaseStatus.Completed]: SubmissionConfig.Android.ReleaseStatus.COMPLETED,
[SubmissionAndroidReleaseStatus.Halted]: SubmissionConfig.Android.ReleaseStatus.HALTED,
};
const graphQlTrackToConfigTrack = {
[SubmissionAndroidTrack.Production]: SubmissionConfig.Android.ReleaseTrack.PRODUCTION,
[SubmissionAndroidTrack.Beta]: SubmissionConfig.Android.ReleaseTrack.BETA,
[SubmissionAndroidTrack.Alpha]: SubmissionConfig.Android.ReleaseTrack.ALPHA,
[SubmissionAndroidTrack.Internal]: SubmissionConfig.Android.ReleaseTrack.INTERNAL,
};
+57 -57
View File
@@ -4,9 +4,9 @@ import { Errors, Flags } from '@oclif/core';
import chalk from 'chalk';
import nullthrows from 'nullthrows';
// import { getExpoWebsiteBaseUrl } from '../../api';
import { getExpoWebsiteBaseUrl } from '../../api';
import { ensureBranchExistsAsync } from '../../branch/queries';
import { EnvironmentVariableEnvironment } from '../../build/utils/environment';
import { transformFingerprintSource } from '../../build/graphql';
import { ensureRepoIsCleanAsync } from '../../build/utils/repository';
import { getUpdateGroupUrl } from '../../build/utils/url';
import EasCommand from '../../commandUtils/EasCommand';
@@ -15,6 +15,7 @@ import { getPaginatedQueryOptions } from '../../commandUtils/pagination';
import fetch from '../../fetch';
import {
AssetMapSourceInput,
EnvironmentVariableEnvironment,
FingerprintInfoGroup as GraphqlFingerprintInfoGroup,
PublishUpdateGroupInput,
StatuspageServiceName,
@@ -23,7 +24,7 @@ import {
UpdateRolloutInfoGroup,
} from '../../graphql/generated';
import { PublishMutation } from '../../graphql/mutations/PublishMutation';
// import { AppQuery } from '../../graphql/queries/AppQuery';
import { AppQuery } from '../../graphql/queries/AppQuery';
import Log, { learnMore, link } from '../../log';
import { ora } from '../../ora';
import { RequestedPlatform } from '../../platform';
@@ -37,7 +38,7 @@ import {
buildUnsortedUpdateInfoGroupAsync,
collectAssetsAsync,
filterCollectedAssetsByRequestedPlatforms,
// findCompatibleBuildsAsync,
findCompatibleBuildsAsync,
generateEasMetadataAsync,
getBranchNameForCommandAsync,
getRuntimeToPlatformsAndFingerprintInfoMappingFromRuntimeVersionInfoObjects,
@@ -487,7 +488,10 @@ export default class UpdatePublish extends EasCommand {
(prev, [platform, fingerprintInfo]) => {
return {
...prev,
[platform]: fingerprintInfo,
[platform]: {
...fingerprintInfo,
fingerprintSource: transformFingerprintSource(fingerprintInfo.fingerprintSource),
},
};
},
{} as GraphqlFingerprintInfoGroup
@@ -590,11 +594,11 @@ export default class UpdatePublish extends EasCommand {
Log.addNewLineIfNone();
// const runtimeToCompatibleBuilds = await Promise.all(
// runtimeToPlatformsAndFingerprintInfoAndFingerprintSourceMapping.map(obj =>
// findCompatibleBuildsAsync(graphqlClient, projectId, obj)
// )
// );
const runtimeToCompatibleBuilds = await Promise.all(
runtimeToPlatformsAndFingerprintInfoAndFingerprintSourceMapping.map(obj =>
findCompatibleBuildsAsync(graphqlClient, projectId, obj)
)
);
for (const runtime of uniqBy(
runtimeToPlatformsAndFingerprintInfoMapping,
@@ -668,56 +672,52 @@ export default class UpdatePublish extends EasCommand {
Log.addNewLineIfNone();
}
// NOTE(brentvatne): temporarily disable logging this until we can revisit the formatting
// and the logic for it - it's a bit too aggressive right now, and warns even if you're
// not using EAS Build
//
// const fingerprintsWithoutCompatibleBuilds = runtimeToCompatibleBuilds.find(
// ({ runtimeVersion }) => runtimeVersion === runtime.runtimeVersion
// )?.fingerprintInfoGroupWithCompatibleBuilds;
// if (fingerprintsWithoutCompatibleBuilds) {
// const missingBuilds = Object.entries(fingerprintsWithoutCompatibleBuilds).filter(
// ([_platform, fingerprintInfo]) => !fingerprintInfo.build
// );
// if (missingBuilds.length > 0) {
// const project = await AppQuery.byIdAsync(graphqlClient, projectId);
// Log.warn('No compatible builds found for the following fingerprints:');
// for (const [platform, fingerprintInfo] of missingBuilds) {
// const fingerprintUrl = new URL(
// `/accounts/${project.ownerAccount.name}/projects/${project.slug}/fingerprints/${fingerprintInfo.fingerprintHash}`,
// getExpoWebsiteBaseUrl()
// );
// Log.warn(
// formatFields(
// [
// {
// label: `${this.prettyPlatform(platform)} fingerprint`,
// value: fingerprintInfo.fingerprintHash,
// },
// { label: 'URL', value: fingerprintUrl.toString() },
// ],
// {
// labelFormat: label => ` ${chalk.dim(label)}:`,
// }
// )
// );
// Log.addNewLineIfNone();
// }
// }
// }
const fingerprintsWithoutCompatibleBuilds = runtimeToCompatibleBuilds.find(
({ runtimeVersion }) => runtimeVersion === runtime.runtimeVersion
)?.fingerprintInfoGroupWithCompatibleBuilds;
if (fingerprintsWithoutCompatibleBuilds) {
const missingBuilds = Object.entries(fingerprintsWithoutCompatibleBuilds).filter(
([_platform, fingerprintInfo]) => !fingerprintInfo.build
);
if (missingBuilds.length > 0) {
const project = await AppQuery.byIdAsync(graphqlClient, projectId);
Log.warn('No compatible builds found for the following fingerprints:');
for (const [platform, fingerprintInfo] of missingBuilds) {
const fingerprintUrl = new URL(
`/accounts/${project.ownerAccount.name}/projects/${project.slug}/fingerprints/${fingerprintInfo.fingerprintHash}`,
getExpoWebsiteBaseUrl()
);
Log.warn(
formatFields(
[
{
label: `${this.prettyPlatform(platform)} fingerprint`,
value: fingerprintInfo.fingerprintHash,
},
{ label: 'URL', value: fingerprintUrl.toString() },
],
{
labelFormat: label => ` ${chalk.dim(label)}:`,
}
)
);
Log.addNewLineIfNone();
}
}
}
}
}
// private prettyPlatform(updatePlatform: string): string {
// switch (updatePlatform) {
// case 'android':
// return 'Android';
// case 'ios':
// return 'iOS';
// default:
// return updatePlatform;
// }
// }
private prettyPlatform(updatePlatform: string): string {
switch (updatePlatform) {
case 'android':
return 'Android';
case 'ios':
return 'iOS';
default:
return updatePlatform;
}
}
private sanitizeFlags(flags: RawUpdateFlags): UpdateFlags {
const nonInteractive = flags['non-interactive'] ?? false;
@@ -6,8 +6,7 @@ import EasCommand from '../../commandUtils/EasCommand';
import { promptAsync } from '../../prompts';
export default class UpdateRollback extends EasCommand {
static override description =
'Roll back to an embedded update or an existing update. Users wishing to run this command non-interactively should instead execute "eas update:republish" or "eas update:roll-back-to-embedded".';
static override description = 'roll back to an embedded update or an existing update';
static override flags = {
'private-key-path': Flags.string({
+21 -23
View File
@@ -154,6 +154,8 @@ export default class WorkflowRun extends EasCommand {
if (error instanceof CombinedError) {
WorkflowFile.maybePrintWorkflowFileValidationErrors({
error,
accountName: account.name,
projectName,
});
throw error;
@@ -446,15 +448,24 @@ export function parseJsonInputs(jsonString: string): Record<string, string> {
// https://github.com/colinhacks/zod/issues/2985#issuecomment-2230692578
const booleanLike = z.union([
z.boolean(),
z.codec(z.number(), z.boolean(), {
decode: n => !!n,
encode: b => (b ? 1 : 0),
}),
z.stringbool({ truthy: ['true', 'True'], falsy: ['false', 'False'] }),
z.number().pipe(z.coerce.boolean()),
z.preprocess(val => {
if (typeof val === 'string') {
if (val.toLowerCase() === 'true') {
return true;
}
if (val.toLowerCase() === 'false') {
return false;
}
}
return val;
}, z.boolean()),
]);
const stringLike = z.codec(
z.union([
const stringLike = z
.union([
// We're going to coerce numbers and strings into strings.
z.number(),
z.string(),
@@ -464,26 +475,13 @@ const stringLike = z.codec(
// and parses both as JS `true` -- if we stringified that,
// we would lose the capital "T" which may not be what the user expects,
// - nulls - user should do `"null"` or not pass the property at all.
]),
z.string(),
{
decode: value => {
if (typeof value === 'string') {
return value;
}
if (typeof value === 'number') {
return String(value);
}
throw new Error(`Cannot convert ${typeof value} to string: ${value}`);
},
encode: value => value,
}
);
])
.pipe(z.coerce.string());
export const WorkflowDispatchInputZ = z
.object({
description: stringLike.optional().describe('Description of the input'),
required: booleanLike.default(false).describe('Whether the input is required.'),
required: booleanLike.default(false).describe('Whether the input is required'),
})
.and(
z.union([
@@ -1,11 +1,12 @@
import { CombinedError } from '@urql/core';
import * as YAML from 'yaml';
import EasCommand from '../../commandUtils/EasCommand';
import { EASNonInteractiveFlag } from '../../commandUtils/flags';
import {
logWorkflowValidationErrors,
validateWorkflowFileAsync,
} from '../../commandUtils/workflow/validation';
import { WorkflowRevisionMutation } from '../../graphql/mutations/WorkflowRevisionMutation';
import Log from '../../log';
import { ora } from '../../ora';
import { getOwnerAccountForProjectIdAsync } from '../../project/projectUtils';
import { WorkflowFile } from '../../utils/workflowFile';
export class WorkflowValidate extends EasCommand {
@@ -26,7 +27,6 @@ export class WorkflowValidate extends EasCommand {
static override contextDefinition = {
...this.ContextOptions.DynamicProjectConfig,
...this.ContextOptions.ProjectDir,
...this.ContextOptions.ProjectId,
...this.ContextOptions.LoggedIn,
};
@@ -36,30 +36,67 @@ export class WorkflowValidate extends EasCommand {
flags,
} = await this.parse(WorkflowValidate);
const spinner = ora().start('Validating the workflow YAML file…');
try {
const {
loggedIn: { graphqlClient },
projectDir,
projectId,
} = await this.getContextAsync(WorkflowValidate, {
nonInteractive: flags['non-interactive'],
withServerSideEnvironment: null,
});
const {
getDynamicPrivateProjectConfigAsync,
loggedIn: { graphqlClient },
projectDir,
} = await this.getContextAsync(WorkflowValidate, {
nonInteractive: flags['non-interactive'],
withServerSideEnvironment: null,
});
const {
projectId,
exp: { slug: projectName },
} = await getDynamicPrivateProjectConfigAsync();
const account = await getOwnerAccountForProjectIdAsync(graphqlClient, projectId);
const spinner = ora().start('Validating the workflow YAML file…');
try {
const workflowFileContents = await WorkflowFile.readWorkflowFileContentsAsync({
projectDir,
filePath,
});
Log.log(`Using workflow file from ${workflowFileContents.filePath}`);
await validateWorkflowFileAsync(workflowFileContents, projectDir, graphqlClient, projectId);
const parsedYaml = YAML.parse(workflowFileContents.yamlConfig);
// Check if the parsed result is empty or null
if (
parsedYaml === null ||
parsedYaml === undefined ||
(typeof parsedYaml === 'object' && Object.keys(parsedYaml).length === 0)
) {
throw new Error('YAML file is empty or contains only comments.');
}
await WorkflowRevisionMutation.validateWorkflowYamlConfigAsync(graphqlClient, {
appId: projectId,
yamlConfig: workflowFileContents.yamlConfig,
});
spinner.succeed('Workflow configuration YAML is valid.');
} catch (error) {
spinner.fail('Workflow configuration YAML is not valid.');
logWorkflowValidationErrors(error);
if (error instanceof YAML.YAMLParseError) {
Log.error(`YAML syntax error: ${error.message}`);
} else if (error instanceof CombinedError) {
WorkflowFile.maybePrintWorkflowFileValidationErrors({
error,
accountName: account.name,
projectName,
});
throw error;
} else if (error instanceof Error) {
Log.error(error.message);
} else {
Log.error(`Unexpected error: ${String(error)}`);
}
throw error;
}
}
}
+13 -109
View File
@@ -1,6 +1,3 @@
import chalk from 'chalk';
import { formatGraphQLBuildArtifacts } from '../../build/utils/formatBuild';
import { getWorkflowRunUrl } from '../../build/utils/url';
import EasCommand from '../../commandUtils/EasCommand';
import { EASNonInteractiveFlag, EasJsonOnlyFlag } from '../../commandUtils/flags';
@@ -10,52 +7,12 @@ import {
} from '../../commandUtils/workflow/stateMachine';
import { WorkflowTriggerType } from '../../commandUtils/workflow/types';
import { computeTriggerInfoForWorkflowRun } from '../../commandUtils/workflow/utils';
import {
BuildArtifacts,
WorkflowArtifact,
WorkflowJobType,
WorkflowRunByIdWithJobsQuery,
} from '../../graphql/generated';
import { WorkflowRunByIdWithJobsQuery } from '../../graphql/generated';
import { WorkflowRunQuery } from '../../graphql/queries/WorkflowRunQuery';
import Log, { link } from '../../log';
import formatFields, { FormatFieldsItem } from '../../utils/formatFields';
import formatFields from '../../utils/formatFields';
import { enableJsonOutput, printJsonOnlyOutput } from '../../utils/json';
type ReducedWorkflowArtifact = Omit<
WorkflowArtifact,
'createdAt' | 'jobRun' | 'storageType' | 'updatedAt'
>;
type WorkflowJobOutput =
WorkflowRunByIdWithJobsQuery['workflowRuns']['byId']['jobs'][number]['outputs'];
type WorkflowJobResult = WorkflowRunByIdWithJobsQuery['workflowRuns']['byId']['jobs'][number] & {
artifacts?: ReducedWorkflowArtifact[] | BuildArtifacts | undefined;
output?: WorkflowJobOutput | undefined;
};
type WorkflowRunResult = WorkflowRunByIdWithJobsQuery['workflowRuns']['byId'] & {
logURL?: string | undefined;
triggerType?: WorkflowTriggerType | undefined;
trigger?: string | null;
jobs: WorkflowJobResult[];
};
const processedOutputs: (job: WorkflowJobResult) => FormatFieldsItem[] = job => {
const result: FormatFieldsItem[] = [];
const keys = job.outputs ? Object.keys(job.outputs) : [];
keys.forEach(key => {
result.push({
label: ` ${key}`,
get value(): string {
const value = job.outputs[key];
return typeof value === 'string' ? value : JSON.stringify(value, null, 2);
},
});
});
return result;
};
export default class WorkflowView extends EasCommand {
static override description =
'view details for a workflow run, including jobs. If no run ID is provided, you will be prompted to select from recent workflow runs for the current project.';
@@ -103,6 +60,11 @@ export default class WorkflowView extends EasCommand {
}
const idToQuery = actionResult.runId ?? '';
type WorkflowRunResult = WorkflowRunByIdWithJobsQuery['workflowRuns']['byId'] & {
logURL?: string;
triggerType?: WorkflowTriggerType;
trigger?: string | null;
};
const result: WorkflowRunResult = await WorkflowRunQuery.withJobsByIdAsync(
graphqlClient,
idToQuery,
@@ -114,18 +76,9 @@ export default class WorkflowView extends EasCommand {
result.triggerType = triggerType;
result.trigger = trigger;
const processedJobs: WorkflowJobResult[] = result.jobs.map(job => {
const processedJob = job as WorkflowJobResult;
if (job.type === WorkflowJobType.Build) {
processedJob.artifacts = job.turtleBuild?.artifacts ?? undefined;
} else {
processedJob.artifacts = job.turtleJobRun?.artifacts;
}
delete processedJob.turtleJobRun;
return processedJob;
result.jobs.forEach(job => {
delete job.turtleJobRun;
});
result.jobs = processedJobs;
result.logURL = getWorkflowRunUrl(
result.workflow.app.ownerAccount.name,
result.workflow.app.name,
@@ -145,7 +98,7 @@ export default class WorkflowView extends EasCommand {
{ label: 'Trigger', value: result.trigger ?? 'null' },
{
label: 'Git Commit Message',
value: result.gitCommitMessage?.split('\n')[0] ?? 'null',
value: result.gitCommitMessage?.split('\n')[0] ?? null ?? 'null',
},
{ label: 'Status', value: result.status },
{ label: 'Errors', value: result.errors.map(error => error.title).join('\n') },
@@ -155,7 +108,7 @@ export default class WorkflowView extends EasCommand {
])
);
Log.addNewLineIfNone();
result.jobs.forEach((job: WorkflowJobResult) => {
result.jobs.forEach(job => {
Log.log(
formatFields([
{ label: 'Job ID', value: job.id },
@@ -165,59 +118,10 @@ export default class WorkflowView extends EasCommand {
{ label: ' Type', value: job.type },
{ label: ' Created At', value: job.createdAt },
{ label: ' Updated At', value: job.updatedAt },
{ label: ' Outputs', value: JSON.stringify(job.outputs, null, 2) },
{ label: ' Errors', value: job.errors.map(error => error.title).join('\n') },
])
);
if (job.errors.length > 0) {
Log.gray(chalk.dim(' Errors:'));
job.errors.forEach(error => {
Log.log(formatFields([{ label: ` ${error.title}`, value: `${error.message}` }]));
});
}
if (job.outputs) {
const outputs = processedOutputs(job);
if (outputs.length > 0) {
Log.gray(chalk.dim(' Outputs:'));
Log.log(formatFields(outputs));
}
}
if (job.type === WorkflowJobType.Build) {
if (job.turtleBuild?.artifacts) {
Log.gray(chalk.dim(' Artifacts:'));
Log.log(
formatFields(
formatGraphQLBuildArtifacts(job.turtleBuild).map(item => {
item.label = ` ${item.label}`;
return item;
})
)
);
}
} else {
const jobArtifacts = job.artifacts as ReducedWorkflowArtifact[];
if (jobArtifacts?.length) {
Log.gray(chalk.dim(' Artifacts:'));
jobArtifacts.forEach(artifact => {
Log.log(
formatFields([
{ label: ' ID', value: artifact.id },
{ label: ' Name', value: artifact.name },
{ label: ' Content Type', value: artifact?.contentType ?? 'null' },
{
label: ' File Size Bytes',
value: artifact?.fileSizeBytes ? `${artifact.fileSizeBytes}` : 'null',
},
{ label: ' Filename', value: artifact.filename },
{
label: ' Download URL',
value: artifact?.downloadUrl ? link(artifact.downloadUrl) : 'null',
},
])
);
Log.addNewLineIfNone();
});
}
}
Log.addNewLineIfNone();
});
}
@@ -44,21 +44,6 @@ export const jester2 = {
featureGates: {},
};
export const robot: Actor = {
__typename: 'Robot',
id: 'robot-id',
firstName: 'Test Robot',
accounts: [
{
id: 'robot-account-id',
name: 'robot-account',
users: [],
},
],
isExpoAdmin: false,
featureGates: {},
};
assert(jester.__typename === 'User');
export const testUsername = jester.username;
export const testSlug = 'testApp';
@@ -227,7 +227,7 @@ async function generateDistributionCertificateAsync(
`✅ Distribution Certificates can be revoked with no side effects for App Store builds.`
)
);
Log.log(learnMore('https://docs.expo.dev/app-signing/app-credentials/#summary'));
Log.log(learnMore('https://docs.expo.dev/distribution/app-signing/#summary'));
Log.newLine();
const { distCertsToRevoke } = await promptAsync({
@@ -76,9 +76,7 @@ async function generatePushKeyAsync(ctx: CredentialsContext): Promise<PushKey> {
}
Log.log(chalk.grey(`⚠️ Revoking a Push Key will affect other apps that rely on it`));
Log.log(
learnMore('https://docs.expo.dev/app-signing/app-credentials/#push-notification-keys')
);
Log.log(learnMore('https://docs.expo.dev/distribution/app-signing/#push-notification-keys'));
Log.log();
const { pushKeysToRevoke } = await promptAsync({
@@ -15,7 +15,6 @@ function createMockBundleId(id: string = 'XXX', capabilities: BundleIdCapability
id,
} as any;
}
const ctx = Object.freeze({ providerId: 123195, teamId: 'MyteamId' });
describe(assertValidOptions, () => {
it(`adds a reason for asserting capability identifiers`, () => {
@@ -30,6 +29,7 @@ describe(assertValidOptions, () => {
describe(syncCapabilitiesForEntitlementsAsync, () => {
it(`does not disable associated domains when MDM managed domains is active`, async () => {
const ctx = { providerId: 123195, teamId: 'MyteamId' };
// https://forums.expo.dev/t/eas-build-failed-on-ios-associated-domains-capability/61662/5
const capabilities = [
{
@@ -67,46 +67,8 @@ describe(syncCapabilitiesForEntitlementsAsync, () => {
]);
});
it('skips syncing capabilities with settings if they do not contain the expected `enabled` field', async () => {
const capabilityJson = {
id: 'U78L9459DG_APPLE_ID_AUTH',
attributes: {
settings: [
{
key: 'APPLE_ID_AUTH_APP_CONSENT',
options: [
{
key: 'PRIMARY_APP_CONSENT',
},
],
},
],
capabilityType: 'APPLE_ID_AUTH',
},
};
const capability = new BundleIdCapability(
ctx,
capabilityJson.id,
capabilityJson.attributes as any
);
const bundleId = createMockBundleId('U78L9459DG', [capability]);
const result = await syncCapabilitiesForEntitlementsAsync(
bundleId,
{
'com.apple.developer.applesignin': ['Default'],
},
noBroadcastNotificationOption
);
expect(result).toStrictEqual({
enabled: [],
disabled: [],
});
expect(bundleId.updateBundleIdCapabilityAsync).not.toHaveBeenCalled();
});
describe('capabilities with settings', () => {
const ctx = { providerId: 123195, teamId: 'MyteamId' };
const capabilities = [
{
id: 'U78L9459DG_APPLE_ID_AUTH',
@@ -304,6 +266,7 @@ describe(syncCapabilitiesForEntitlementsAsync, () => {
});
describe('given a bundleId with a capability that is enabled', () => {
const ctx = { providerId: 123195, teamId: 'MyteamId' };
const remote = {
id: 'UFJ54VZ75A_ACCESS_WIFI_INFORMATION',
attributes: {
@@ -417,7 +380,7 @@ describe(syncCapabilitiesForEntitlementsAsync, () => {
noBroadcastNotificationOption
);
expect(bundleId.updateBundleIdCapabilityAsync).toHaveBeenCalledWith([
expect(bundleId.updateBundleIdCapabilityAsync).toBeCalledWith([
{ capabilityType: 'HEALTHKIT', option: 'ON' },
{ capabilityType: 'APPLE_PAY', option: 'ON' },
{ capabilityType: 'ICLOUD', option: 'ON' },
@@ -733,7 +696,7 @@ describe(syncCapabilitiesForEntitlementsAsync, () => {
noBroadcastNotificationOption
);
expect(bundleId.updateBundleIdCapabilityAsync).toHaveBeenCalledWith([
expect(bundleId.updateBundleIdCapabilityAsync).toBeCalledWith([
{ capabilityType: 'HEALTHKIT', option: 'ON' },
]);
@@ -823,7 +786,7 @@ describe(syncCapabilitiesForEntitlementsAsync, () => {
}
);
expect(bundleId.updateBundleIdCapabilityAsync).not.toHaveBeenCalled();
expect(bundleId.updateBundleIdCapabilityAsync).not.toBeCalled();
expect(results.disabled).toStrictEqual([]);
expect(results.enabled).toStrictEqual([]);
@@ -844,7 +807,7 @@ describe(syncCapabilitiesForEntitlementsAsync, () => {
noBroadcastNotificationOption
);
expect(bundleId.updateBundleIdCapabilityAsync).not.toHaveBeenCalled();
expect(bundleId.updateBundleIdCapabilityAsync).not.toBeCalled();
expect(results.disabled).toStrictEqual([]);
expect(results.enabled).toStrictEqual([]);
@@ -129,7 +129,7 @@ function getCapabilitiesToEnable(
const { op } = operation;
if (Log.isDebug) {
Log.log(`Will ${op} remote capability: ${key} (${staticCapabilityInfo.name}).`);
Log.log(`Will ${op} remote capability: ${key} (${staticCapabilityInfo.name}.`);
}
if (op === 'enable') {
enabledCapabilityNames.push(staticCapabilityInfo.name);
@@ -12,8 +12,6 @@ import { JSONObject, JSONValue } from '@expo/json-file';
import { invariant } from 'graphql/jsutils/invariant';
import nullthrows from 'nullthrows';
import Log from '../../../log';
const validateBooleanOptions = (options: any): boolean => {
return typeof options === 'boolean';
};
@@ -88,32 +86,21 @@ const capabilityWithSettingsSyncOperation: GetSyncOperation = ({
if (!existingRemote) {
return enableOp;
}
const { attributes, id } = existingRemote;
if ('enabled' in attributes) {
// the `enabled` field should be available as per https://developer.apple.com/documentation/appstoreconnectapi/capabilitysetting
const existingEnabled = attributes.enabled === true;
invariant(
'enabled' in existingRemote.attributes,
`Expected "enabled" attribute in ${existingRemote.id}`
);
const existingEnabled = existingRemote.attributes.enabled === true;
const newOption = entitlementValue ? CapabilityTypeOption.ON : CapabilityTypeOption.OFF;
// If both are enabled and the existing one has settings, skip the update
if (existingEnabled && entitlementValue && attributes.settings) {
return skipOp;
}
const newOption = entitlementValue ? CapabilityTypeOption.ON : CapabilityTypeOption.OFF;
// If the states don't match, we need to update
const newEnabled = newOption === CapabilityTypeOption.ON;
return existingEnabled === newEnabled ? skipOp : { op: 'enable', option: newOption };
} else {
if (Log.isDebug) {
Log.log(
`Expected the "enabled" attribute in ${id} but it was not present (attributes: ${JSON.stringify(
attributes,
null,
2
)}). Will skip syncing this capability.`
);
}
// If both are enabled and the existing one has settings, skip the update
if (existingEnabled && entitlementValue && existingRemote.attributes.settings) {
return skipOp;
}
// If the states don't match, we need to update
const newEnabled = newOption === CapabilityTypeOption.ON;
return existingEnabled === newEnabled ? skipOp : { op: 'enable', option: newOption };
};
export type CapabilityClassifier = {
+122 -166
View File
@@ -21,10 +21,8 @@ export type Scalars = {
Float: { input: number; output: number; }
DateTime: { input: any; output: any; }
DevDomainName: { input: any; output: any; }
EnvironmentVariableEnvironment: { input: any; output: any; }
JSON: { input: any; output: any; }
JSONObject: { input: any; output: any; }
SubmissionAndroidTrack: { input: any; output: any; }
WorkerDeploymentIdentifier: { input: any; output: any; }
WorkerDeploymentRequestID: { input: any; output: any; }
};
@@ -163,8 +161,6 @@ export type Account = {
sentryInstallation?: Maybe<SentryInstallation>;
/** Snacks associated with this account */
snacks: Array<Snack>;
/** Allowed SSO providers for this account */
ssoAllowedAuthProviders: Array<AuthProviderIdentifier>;
/** SSO configuration for this account */
ssoConfiguration?: Maybe<AccountSsoConfiguration>;
/** Subscription info visible to members that have VIEWER role */
@@ -388,7 +384,7 @@ export type AccountEnvironmentSecretsArgs = {
* data and settings. Actors may own and be members of accounts.
*/
export type AccountEnvironmentVariablesArgs = {
environment?: InputMaybe<Scalars['EnvironmentVariableEnvironment']['input']>;
environment?: InputMaybe<EnvironmentVariableEnvironment>;
filterNames?: InputMaybe<Array<Scalars['String']['input']>>;
};
@@ -398,7 +394,7 @@ export type AccountEnvironmentVariablesArgs = {
* data and settings. Actors may own and be members of accounts.
*/
export type AccountEnvironmentVariablesIncludingSensitiveArgs = {
environment?: InputMaybe<Scalars['EnvironmentVariableEnvironment']['input']>;
environment?: InputMaybe<EnvironmentVariableEnvironment>;
filterNames?: InputMaybe<Array<Scalars['String']['input']>>;
};
@@ -700,8 +696,6 @@ export type AccountSsoConfigurationMutation = {
deleteAccountSSOConfiguration: DeleteAccountSsoConfigurationResult;
/** Update an AccountSSOConfiguration */
updateAccountSSOConfiguration: AccountSsoConfiguration;
/** Update just the client secret of an AccountSSOConfiguration */
updateAccountSSOConfigurationClientSecret: AccountSsoConfiguration;
};
@@ -721,12 +715,6 @@ export type AccountSsoConfigurationMutationUpdateAccountSsoConfigurationArgs = {
id: Scalars['ID']['input'];
};
export type AccountSsoConfigurationMutationUpdateAccountSsoConfigurationClientSecretArgs = {
clientSecret: Scalars['String']['input'];
id: Scalars['ID']['input'];
};
/** Public auth configuration data for an SSO account. */
export type AccountSsoConfigurationPublicData = {
__typename?: 'AccountSSOConfigurationPublicData';
@@ -1127,7 +1115,7 @@ export type AndroidJobInput = {
cache?: InputMaybe<BuildCacheInput>;
customBuildConfig?: InputMaybe<CustomBuildConfigInput>;
developmentClient?: InputMaybe<Scalars['Boolean']['input']>;
environment?: InputMaybe<Scalars['EnvironmentVariableEnvironment']['input']>;
environment?: InputMaybe<EnvironmentVariableEnvironment>;
experimental?: InputMaybe<Scalars['JSONObject']['input']>;
gradleCommand?: InputMaybe<Scalars['String']['input']>;
loggerLevel?: InputMaybe<WorkerLoggerLevel>;
@@ -1237,11 +1225,12 @@ export type AndroidSubmissionConfig = {
archiveType?: Maybe<SubmissionAndroidArchiveType>;
releaseStatus?: Maybe<SubmissionAndroidReleaseStatus>;
rollout?: Maybe<Scalars['Float']['output']>;
track: Scalars['String']['output'];
track: SubmissionAndroidTrack;
};
export type AndroidSubmissionConfigInput = {
applicationIdentifier?: InputMaybe<Scalars['String']['input']>;
archiveUrl?: InputMaybe<Scalars['String']['input']>;
changelog?: InputMaybe<Scalars['String']['input']>;
changesNotSentForReview?: InputMaybe<Scalars['Boolean']['input']>;
googleServiceAccountKeyId?: InputMaybe<Scalars['String']['input']>;
@@ -1249,7 +1238,7 @@ export type AndroidSubmissionConfigInput = {
isVerboseFastlaneEnabled?: InputMaybe<Scalars['Boolean']['input']>;
releaseStatus?: InputMaybe<SubmissionAndroidReleaseStatus>;
rollout?: InputMaybe<Scalars['Float']['input']>;
track: Scalars['SubmissionAndroidTrack']['input'];
track: SubmissionAndroidTrack;
};
/** Represents an Exponent App (or Experience in legacy terms) */
@@ -1512,14 +1501,14 @@ export type AppEnvironmentSecretsArgs = {
/** Represents an Exponent App (or Experience in legacy terms) */
export type AppEnvironmentVariablesArgs = {
environment?: InputMaybe<Scalars['EnvironmentVariableEnvironment']['input']>;
environment?: InputMaybe<EnvironmentVariableEnvironment>;
filterNames?: InputMaybe<Array<Scalars['String']['input']>>;
};
/** Represents an Exponent App (or Experience in legacy terms) */
export type AppEnvironmentVariablesIncludingSensitiveArgs = {
environment?: InputMaybe<Scalars['EnvironmentVariableEnvironment']['input']>;
environment?: InputMaybe<EnvironmentVariableEnvironment>;
filterNames?: InputMaybe<Array<Scalars['String']['input']>>;
};
@@ -2793,7 +2782,6 @@ export enum AuthProtocolType {
}
export enum AuthProviderIdentifier {
AmazonFederate = 'AMAZON_FEDERATE',
Generic = 'GENERIC',
GoogleWs = 'GOOGLE_WS',
MsEntraId = 'MS_ENTRA_ID',
@@ -2945,7 +2933,7 @@ export type Build = ActivityTimelineProjectActivity & BuildOrBuildJob & {
reactNativeVersion?: Maybe<Scalars['String']['output']>;
releaseChannel?: Maybe<Scalars['String']['output']>;
requiredPackageManager?: Maybe<Scalars['String']['output']>;
resolvedEnvironment?: Maybe<Scalars['EnvironmentVariableEnvironment']['output']>;
resolvedEnvironment?: Maybe<EnvironmentVariableEnvironment>;
/**
* The builder resource class requested by the developer
* @deprecated Use resourceClassDisplayName instead
@@ -2959,15 +2947,12 @@ export type Build = ActivityTimelineProjectActivity & BuildOrBuildJob & {
/** @deprecated Use 'runtime' field instead. */
runtimeVersion?: Maybe<Scalars['String']['output']>;
sdkVersion?: Maybe<Scalars['String']['output']>;
/** @deprecated Check logs instead. */
selectedImage?: Maybe<Scalars['String']['output']>;
status: BuildStatus;
submissions: Array<Submission>;
updateChannel?: Maybe<UpdateChannel>;
updatedAt: Scalars['DateTime']['output'];
waiverType?: Maybe<EasBuildWaiverType>;
workerStartedAt?: Maybe<Scalars['DateTime']['output']>;
workflowJob?: Maybe<WorkflowJob>;
};
@@ -3158,7 +3143,6 @@ export type BuildMetadataInput = {
iosEnterpriseProvisioning?: InputMaybe<BuildIosEnterpriseProvisioning>;
isGitWorkingTreeDirty?: InputMaybe<Scalars['Boolean']['input']>;
message?: InputMaybe<Scalars['String']['input']>;
projectMetadataFile?: InputMaybe<ProjectMetadataFileInput>;
reactNativeVersion?: InputMaybe<Scalars['String']['input']>;
releaseChannel?: InputMaybe<Scalars['String']['input']>;
requiredPackageManager?: InputMaybe<Scalars['String']['input']>;
@@ -3166,6 +3150,7 @@ export type BuildMetadataInput = {
runWithNoWaitFlag?: InputMaybe<Scalars['Boolean']['input']>;
runtimeVersion?: InputMaybe<Scalars['String']['input']>;
sdkVersion?: InputMaybe<Scalars['String']['input']>;
selectedImage?: InputMaybe<Scalars['String']['input']>;
simulator?: InputMaybe<Scalars['Boolean']['input']>;
trackingContext?: InputMaybe<Scalars['JSONObject']['input']>;
username?: InputMaybe<Scalars['String']['input']>;
@@ -3567,6 +3552,7 @@ export type CreateAndConfigureRepositoryInput = {
export type CreateAndroidSubmissionInput = {
appId: Scalars['ID']['input'];
archiveSource?: InputMaybe<SubmissionArchiveSourceInput>;
archiveUrl?: InputMaybe<Scalars['String']['input']>;
config: AndroidSubmissionConfigInput;
submittedBuildId?: InputMaybe<Scalars['ID']['input']>;
};
@@ -3584,7 +3570,7 @@ export type CreateEnvironmentSecretInput = {
};
export type CreateEnvironmentVariableInput = {
environments?: InputMaybe<Array<Scalars['EnvironmentVariableEnvironment']['input']>>;
environments?: InputMaybe<Array<EnvironmentVariableEnvironment>>;
fileName?: InputMaybe<Scalars['String']['input']>;
name: Scalars['String']['input'];
overwrite?: InputMaybe<Scalars['Boolean']['input']>;
@@ -3607,7 +3593,7 @@ export type CreateGitHubBuildTriggerInput = {
appId: Scalars['ID']['input'];
autoSubmit: Scalars['Boolean']['input'];
buildProfile: Scalars['String']['input'];
environment?: InputMaybe<Scalars['EnvironmentVariableEnvironment']['input']>;
environment?: InputMaybe<EnvironmentVariableEnvironment>;
executionBehavior: GitHubBuildTriggerExecutionBehavior;
isActive: Scalars['Boolean']['input'];
platform: AppPlatform;
@@ -3644,6 +3630,7 @@ export type CreateGitHubRepositorySettingsInput = {
export type CreateIosSubmissionInput = {
appId: Scalars['ID']['input'];
archiveSource?: InputMaybe<SubmissionArchiveSourceInput>;
archiveUrl?: InputMaybe<Scalars['String']['input']>;
config: IosSubmissionConfigInput;
submittedBuildId?: InputMaybe<Scalars['ID']['input']>;
};
@@ -3655,8 +3642,9 @@ export type CreateSentryProjectInput = {
};
export type CreateSharedEnvironmentVariableInput = {
environments?: InputMaybe<Array<Scalars['EnvironmentVariableEnvironment']['input']>>;
environments?: InputMaybe<Array<EnvironmentVariableEnvironment>>;
fileName?: InputMaybe<Scalars['String']['input']>;
isGlobal?: InputMaybe<Scalars['Boolean']['input']>;
name: Scalars['String']['input'];
overwrite?: InputMaybe<Scalars['Boolean']['input']>;
type?: InputMaybe<EnvironmentSecretType>;
@@ -3760,11 +3748,6 @@ export enum CustomDomainStatus {
TimedOut = 'TIMED_OUT'
}
export enum DashboardViewPin {
Activity = 'ACTIVITY',
Overview = 'OVERVIEW'
}
export type DatasetTimespan = {
end: Scalars['DateTime']['input'];
start: Scalars['DateTime']['input'];
@@ -3921,6 +3904,8 @@ export type Deployment = {
builds: DeploymentBuildsConnection;
channel: UpdateChannel;
id: Scalars['ID']['output'];
/** Deployment query field */
insights: DeploymentInsights;
/** Ordered the same way as 'updateBranches' in UpdateChannel */
latestUpdatesPerBranch: Array<LatestUpdateOnBranch>;
runtime: Runtime;
@@ -3984,6 +3969,41 @@ export type DeploymentFilterInput = {
runtimeVersion?: InputMaybe<Scalars['String']['input']>;
};
export type DeploymentInsights = {
__typename?: 'DeploymentInsights';
cumulativeMetricsOverTime: DeploymentCumulativeMetricsOverTimeData;
embeddedUpdateTotalUniqueUsers: Scalars['Int']['output'];
embeddedUpdateUniqueUsersOverTime: UniqueUsersOverTimeData;
id: Scalars['ID']['output'];
mostPopularUpdates: Array<Update>;
uniqueUsersOverTime: UniqueUsersOverTimeData;
};
export type DeploymentInsightsCumulativeMetricsOverTimeArgs = {
timespan: InsightsTimespan;
};
export type DeploymentInsightsEmbeddedUpdateTotalUniqueUsersArgs = {
timespan: InsightsTimespan;
};
export type DeploymentInsightsEmbeddedUpdateUniqueUsersOverTimeArgs = {
timespan: InsightsTimespan;
};
export type DeploymentInsightsMostPopularUpdatesArgs = {
timespan: InsightsTimespan;
};
export type DeploymentInsightsUniqueUsersOverTimeArgs = {
timespan: InsightsTimespan;
};
export type DeploymentQuery = {
__typename?: 'DeploymentQuery';
/** Query a Deployment by ID */
@@ -4231,11 +4251,11 @@ export type EnvironmentVariable = {
/** @deprecated Environment variables are automatically linked to all apps */
apps: Array<App>;
createdAt: Scalars['DateTime']['output'];
environments?: Maybe<Array<Scalars['EnvironmentVariableEnvironment']['output']>>;
environments?: Maybe<Array<EnvironmentVariableEnvironment>>;
fileName?: Maybe<Scalars['String']['output']>;
id: Scalars['ID']['output'];
isGlobal?: Maybe<Scalars['Boolean']['output']>;
linkedEnvironments?: Maybe<Array<Scalars['EnvironmentVariableEnvironment']['output']>>;
linkedEnvironments?: Maybe<Array<EnvironmentVariableEnvironment>>;
name: Scalars['String']['output'];
scope: EnvironmentVariableScope;
type: EnvironmentSecretType;
@@ -4255,6 +4275,12 @@ export type EnvironmentVariableValueArgs = {
includeFileContent?: InputMaybe<Scalars['Boolean']['input']>;
};
export enum EnvironmentVariableEnvironment {
Development = 'DEVELOPMENT',
Preview = 'PREVIEW',
Production = 'PRODUCTION'
}
export type EnvironmentVariableMutation = {
__typename?: 'EnvironmentVariableMutation';
/** Create bulk env variables for an Account */
@@ -4334,11 +4360,11 @@ export type EnvironmentVariableWithSecret = {
__typename?: 'EnvironmentVariableWithSecret';
apps: Array<App>;
createdAt: Scalars['DateTime']['output'];
environments?: Maybe<Array<Scalars['EnvironmentVariableEnvironment']['output']>>;
environments?: Maybe<Array<EnvironmentVariableEnvironment>>;
fileName?: Maybe<Scalars['String']['output']>;
id: Scalars['ID']['output'];
isGlobal: Scalars['Boolean']['output'];
linkedEnvironments?: Maybe<Array<Scalars['EnvironmentVariableEnvironment']['output']>>;
linkedEnvironments?: Maybe<Array<EnvironmentVariableEnvironment>>;
name: Scalars['String']['output'];
scope: EnvironmentVariableScope;
sensitive: Scalars['Boolean']['output'];
@@ -4378,24 +4404,11 @@ export type EstimatedUsage = {
id: Scalars['ID']['output'];
limit: Scalars['Float']['output'];
metricType: UsageMetricType;
platformBreakdown?: Maybe<EstimatedUsagePlatformBreakdown>;
service: EasService;
serviceMetric: EasServiceMetric;
value: Scalars['Float']['output'];
};
export type EstimatedUsagePlatformBreakdown = {
__typename?: 'EstimatedUsagePlatformBreakdown';
android: EstimatedUsagePlatformDetail;
ios: EstimatedUsagePlatformDetail;
};
export type EstimatedUsagePlatformDetail = {
__typename?: 'EstimatedUsagePlatformDetail';
limit: Scalars['Float']['output'];
value: Scalars['Float']['output'];
};
export enum Experiment {
Orbit = 'ORBIT'
}
@@ -4656,7 +4669,7 @@ export type GitHubBuildInput = {
autoSubmit?: InputMaybe<Scalars['Boolean']['input']>;
baseDirectory?: InputMaybe<Scalars['String']['input']>;
buildProfile: Scalars['String']['input'];
environment?: InputMaybe<Scalars['EnvironmentVariableEnvironment']['input']>;
environment?: InputMaybe<EnvironmentVariableEnvironment>;
gitRef: Scalars['String']['input'];
platform: AppPlatform;
submitProfile?: InputMaybe<Scalars['String']['input']>;
@@ -4668,7 +4681,7 @@ export type GitHubBuildTrigger = {
autoSubmit: Scalars['Boolean']['output'];
buildProfile: Scalars['String']['output'];
createdAt: Scalars['DateTime']['output'];
environment?: Maybe<Scalars['EnvironmentVariableEnvironment']['output']>;
environment?: Maybe<EnvironmentVariableEnvironment>;
executionBehavior: GitHubBuildTriggerExecutionBehavior;
id: Scalars['ID']['output'];
isActive: Scalars['Boolean']['output'];
@@ -5247,7 +5260,7 @@ export type IosJobInput = {
developmentClient?: InputMaybe<Scalars['Boolean']['input']>;
/** @deprecated */
distribution?: InputMaybe<DistributionType>;
environment?: InputMaybe<Scalars['EnvironmentVariableEnvironment']['input']>;
environment?: InputMaybe<EnvironmentVariableEnvironment>;
experimental?: InputMaybe<Scalars['JSONObject']['input']>;
loggerLevel?: InputMaybe<WorkerLoggerLevel>;
mode?: InputMaybe<BuildMode>;
@@ -5329,6 +5342,7 @@ export type IosSubmissionConfig = {
export type IosSubmissionConfigInput = {
appleAppSpecificPassword?: InputMaybe<Scalars['String']['input']>;
appleIdUsername?: InputMaybe<Scalars['String']['input']>;
archiveUrl?: InputMaybe<Scalars['String']['input']>;
ascApiKey?: InputMaybe<AscApiKeyInput>;
ascApiKeyId?: InputMaybe<Scalars['String']['input']>;
ascAppIdentifier: Scalars['String']['input'];
@@ -5900,12 +5914,6 @@ export enum Permission {
View = 'VIEW'
}
export type PinnedDashboardView = {
__typename?: 'PinnedDashboardView';
account: Account;
view: DashboardViewPin;
};
export type PlanEnablement = Concurrencies | EasTotalPlanEnablement;
export type Project = {
@@ -5937,11 +5945,6 @@ export enum ProjectArchiveSourceType {
Url = 'URL'
}
export type ProjectMetadataFileInput = {
bucketKey: Scalars['String']['input'];
type: ProjectArchiveSourceType;
};
export type ProjectPublicData = {
__typename?: 'ProjectPublicData';
fullName: Scalars['String']['output'];
@@ -5973,7 +5976,7 @@ export type PublishUpdateGroupInput = {
assetMapGroup?: InputMaybe<AssetMapGroup>;
awaitingCodeSigningInfo?: InputMaybe<Scalars['Boolean']['input']>;
branchId: Scalars['String']['input'];
environment?: InputMaybe<Scalars['EnvironmentVariableEnvironment']['input']>;
environment?: InputMaybe<EnvironmentVariableEnvironment>;
excludedAssets?: InputMaybe<Array<PartialManifestAsset>>;
fingerprintInfoGroup?: InputMaybe<FingerprintInfoGroup>;
gitCommitHash?: InputMaybe<Scalars['String']['input']>;
@@ -6247,8 +6250,6 @@ export type RootMutation = {
/** Mutations that create, update, and delete pinned apps */
userAppPins: UserAppPinMutation;
userAuditLog: UserAuditLogMutation;
/** Mutations that create, update, and delete pinned dashboard views */
userDashboardViewPins: UserDashboardViewPinMutation;
/** Mutations that create, delete, and accept UserInvitations */
userInvitation: UserInvitationMutation;
/** Mutations that create, delete, update Webhooks */
@@ -6429,7 +6430,6 @@ export type RootQueryUserByUsernameArgs = {
export type Runtime = {
__typename?: 'Runtime';
app: App;
buildCount: Scalars['Int']['output'];
builds: AppBuildsConnection;
createdAt: Scalars['DateTime']['output'];
deployments: DeploymentsConnection;
@@ -6443,12 +6443,6 @@ export type Runtime = {
};
export type RuntimeBuildCountArgs = {
channel?: InputMaybe<Scalars['String']['input']>;
statuses?: InputMaybe<Array<BuildStatus>>;
};
export type RuntimeBuildsArgs = {
after?: InputMaybe<Scalars['String']['input']>;
before?: InputMaybe<Scalars['String']['input']>;
@@ -6470,7 +6464,6 @@ export type RuntimeDeploymentsArgs = {
export type RuntimeUpdatesArgs = {
after?: InputMaybe<Scalars['String']['input']>;
before?: InputMaybe<Scalars['String']['input']>;
filter?: InputMaybe<RuntimeUpdatesFilterInput>;
first?: InputMaybe<Scalars['Int']['input']>;
last?: InputMaybe<Scalars['Int']['input']>;
};
@@ -6498,7 +6491,6 @@ export type RuntimeFilterInput = {
/** Only return runtimes shared with this branch */
branchId?: InputMaybe<Scalars['String']['input']>;
runtimeVersions?: InputMaybe<Array<Scalars['String']['input']>>;
searchTerm?: InputMaybe<Scalars['String']['input']>;
};
export type RuntimeQuery = {
@@ -6512,10 +6504,6 @@ export type RuntimeQueryByIdArgs = {
runtimeId: Scalars['ID']['input'];
};
export type RuntimeUpdatesFilterInput = {
channel?: InputMaybe<Scalars['String']['input']>;
};
export type RuntimeWithLastActivity = {
__typename?: 'RuntimeWithLastActivity';
lastActivityPostgresSerialized: Scalars['String']['output'];
@@ -6573,7 +6561,6 @@ export type SsoUser = Actor & UserActor & {
location?: Maybe<Scalars['String']['output']>;
notificationSubscriptions: Array<NotificationSubscription>;
pinnedApps: Array<App>;
pinnedDashboardViews: Array<PinnedDashboardView>;
preferences: UserPreferences;
/** Associated accounts */
primaryAccount: Account;
@@ -6937,7 +6924,6 @@ export type Submission = ActivityTimelineProjectActivity & {
status: SubmissionStatus;
submittedBuild?: Maybe<Build>;
updatedAt: Scalars['DateTime']['output'];
workflowJob?: Maybe<WorkflowJob>;
};
export enum SubmissionAndroidArchiveType {
@@ -6952,6 +6938,13 @@ export enum SubmissionAndroidReleaseStatus {
InProgress = 'IN_PROGRESS'
}
export enum SubmissionAndroidTrack {
Alpha = 'ALPHA',
Beta = 'BETA',
Internal = 'INTERNAL',
Production = 'PRODUCTION'
}
export type SubmissionArchiveSourceInput = {
/** Required if the archive source type is GCS_BUILD_APPLICATION_ARCHIVE, GCS_BUILD_APPLICATION_ARCHIVE_ORCHESTRATOR or GCS_SUBMIT_ARCHIVE */
bucketKey?: InputMaybe<Scalars['String']['input']>;
@@ -7122,7 +7115,7 @@ export type Update = ActivityTimelineProjectActivity & {
codeSigningInfo?: Maybe<CodeSigningInfo>;
createdAt: Scalars['DateTime']['output'];
deployments: DeploymentResult;
environment?: Maybe<Scalars['EnvironmentVariableEnvironment']['output']>;
environment?: Maybe<EnvironmentVariableEnvironment>;
expoGoSDKVersion?: Maybe<Scalars['String']['output']>;
fingerprint?: Maybe<Fingerprint>;
gitCommitHash?: Maybe<Scalars['String']['output']>;
@@ -7144,7 +7137,6 @@ export type Update = ActivityTimelineProjectActivity & {
/** @deprecated Use 'runtime' field . */
runtimeVersion: Scalars['String']['output'];
updatedAt: Scalars['DateTime']['output'];
workflowJob?: Maybe<WorkflowJob>;
};
@@ -7320,7 +7312,6 @@ export type UpdateChannelRuntimeInsights = {
export type UpdateChannelRuntimeInsightsCumulativeMetricsOverTimeArgs = {
runtimeVersion: Scalars['String']['input'];
timespan: InsightsTimespan;
};
@@ -7355,9 +7346,10 @@ export type UpdateDeploymentsConnection = {
};
export type UpdateEnvironmentVariableInput = {
environments?: InputMaybe<Array<Scalars['EnvironmentVariableEnvironment']['input']>>;
environments?: InputMaybe<Array<EnvironmentVariableEnvironment>>;
fileName?: InputMaybe<Scalars['String']['input']>;
id: Scalars['ID']['input'];
isGlobal?: InputMaybe<Scalars['Boolean']['input']>;
name?: InputMaybe<Scalars['String']['input']>;
type?: InputMaybe<EnvironmentSecretType>;
value?: InputMaybe<Scalars['String']['input']>;
@@ -7373,7 +7365,7 @@ export type UpdateFilterInput = {
export type UpdateGitHubBuildTriggerInput = {
autoSubmit: Scalars['Boolean']['input'];
buildProfile: Scalars['String']['input'];
environment?: InputMaybe<Scalars['EnvironmentVariableEnvironment']['input']>;
environment?: InputMaybe<EnvironmentVariableEnvironment>;
executionBehavior: GitHubBuildTriggerExecutionBehavior;
isActive: Scalars['Boolean']['input'];
platform: AppPlatform;
@@ -7621,7 +7613,6 @@ export type User = Actor & UserActor & {
/** Pending UserInvitations for this user. Only resolves for the viewer. */
pendingUserInvitations: Array<UserInvitation>;
pinnedApps: Array<App>;
pinnedDashboardViews: Array<PinnedDashboardView>;
preferences: UserPreferences;
/** Associated accounts */
primaryAccount: Account;
@@ -7970,23 +7961,6 @@ export type UserAuditLogQueryByUserIdPaginatedArgs = {
userId: Scalars['ID']['input'];
};
export type UserDashboardViewPinMutation = {
__typename?: 'UserDashboardViewPinMutation';
pinDashboardView: PinnedDashboardView;
unpinDashboardView?: Maybe<PinnedDashboardView>;
};
export type UserDashboardViewPinMutationPinDashboardViewArgs = {
accountId: Scalars['ID']['input'];
view: DashboardViewPin;
};
export type UserDashboardViewPinMutationUnpinDashboardViewArgs = {
accountId: Scalars['ID']['input'];
};
export type UserDataInput = {
email?: InputMaybe<Scalars['String']['input']>;
firstName?: InputMaybe<Scalars['String']['input']>;
@@ -8882,14 +8856,12 @@ export enum WorkflowJobType {
Doc = 'DOC',
Fingerprint = 'FINGERPRINT',
GetBuild = 'GET_BUILD',
GithubComment = 'GITHUB_COMMENT',
MaestroCloud = 'MAESTRO_CLOUD',
MaestroTest = 'MAESTRO_TEST',
Repack = 'REPACK',
RequireApproval = 'REQUIRE_APPROVAL',
Slack = 'SLACK',
Submission = 'SUBMISSION',
Testflight = 'TESTFLIGHT',
Update = 'UPDATE'
}
@@ -8947,18 +8919,10 @@ export type WorkflowRevisionInput = {
export type WorkflowRevisionMutation = {
__typename?: 'WorkflowRevisionMutation';
getOrCreateWorkflowRevisionFromGitRef: WorkflowRevision;
validateWorkflowYamlConfig: Scalars['Boolean']['output'];
};
export type WorkflowRevisionMutationGetOrCreateWorkflowRevisionFromGitRefArgs = {
appId: Scalars['ID']['input'];
fileName: Scalars['String']['input'];
gitRef: Scalars['String']['input'];
};
export type WorkflowRevisionMutationValidateWorkflowYamlConfigArgs = {
appId: Scalars['ID']['input'];
yamlConfig: Scalars['String']['input'];
@@ -9037,7 +9001,6 @@ export type WorkflowRunMutation = {
__typename?: 'WorkflowRunMutation';
cancelWorkflowRun: WorkflowRun;
createWorkflowRun: WorkflowRun;
createWorkflowRunFromGitRef: WorkflowRun;
retryWorkflowRun: WorkflowRun;
};
@@ -9054,13 +9017,6 @@ export type WorkflowRunMutationCreateWorkflowRunArgs = {
};
export type WorkflowRunMutationCreateWorkflowRunFromGitRefArgs = {
gitRef: Scalars['String']['input'];
inputs?: InputMaybe<Scalars['JSONObject']['input']>;
workflowRevisionId: Scalars['ID']['input'];
};
export type WorkflowRunMutationRetryWorkflowRunArgs = {
fromFailedJobs?: InputMaybe<Scalars['Boolean']['input']>;
workflowRunId: Scalars['ID']['input'];
@@ -9651,7 +9607,7 @@ export type CreateAndroidBuildMutationVariables = Exact<{
}>;
export type CreateAndroidBuildMutation = { __typename?: 'RootMutation', build: { __typename?: 'BuildMutation', createAndroidBuild: { __typename?: 'CreateBuildResult', build: { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, gitCommitMessage?: string | null, initialQueuePosition?: number | null, queuePosition?: number | null, estimatedWaitTimeLeftSeconds?: number | null, priority: BuildPriority, createdAt: any, updatedAt: any, message?: string | null, completedAt?: any | null, expirationDate?: any | null, isForIosSimulator: boolean, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null, applicationArchiveUrl?: string | null, buildArtifactsUrl?: string | null } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'SSOUser', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string }, metrics?: { __typename?: 'BuildMetrics', buildWaitTime?: number | null, buildQueueTime?: number | null, buildDuration?: number | null } | null }, deprecationInfo?: { __typename?: 'EASBuildDeprecationInfo', type: EasBuildDeprecationInfoType, message: string } | null } } };
export type CreateAndroidBuildMutation = { __typename?: 'RootMutation', build: { __typename?: 'BuildMutation', createAndroidBuild: { __typename?: 'CreateBuildResult', build: { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, gitCommitMessage?: string | null, initialQueuePosition?: number | null, queuePosition?: number | null, estimatedWaitTimeLeftSeconds?: number | null, priority: BuildPriority, createdAt: any, updatedAt: any, message?: string | null, completedAt?: any | null, expirationDate?: any | null, isForIosSimulator: boolean, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null, applicationArchiveUrl?: string | null, buildArtifactsUrl?: string | null } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'SSOUser', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string }, metrics?: { __typename?: 'BuildMetrics', buildWaitTime?: number | null, buildQueueTime?: number | null, buildDuration?: number | null } | null }, deprecationInfo?: { __typename?: 'EASBuildDeprecationInfo', type: EasBuildDeprecationInfoType, message: string } | null } } };
export type CreateIosBuildMutationVariables = Exact<{
appId: Scalars['ID']['input'];
@@ -9661,7 +9617,7 @@ export type CreateIosBuildMutationVariables = Exact<{
}>;
export type CreateIosBuildMutation = { __typename?: 'RootMutation', build: { __typename?: 'BuildMutation', createIosBuild: { __typename?: 'CreateBuildResult', build: { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, gitCommitMessage?: string | null, initialQueuePosition?: number | null, queuePosition?: number | null, estimatedWaitTimeLeftSeconds?: number | null, priority: BuildPriority, createdAt: any, updatedAt: any, message?: string | null, completedAt?: any | null, expirationDate?: any | null, isForIosSimulator: boolean, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null, applicationArchiveUrl?: string | null, buildArtifactsUrl?: string | null } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'SSOUser', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string }, metrics?: { __typename?: 'BuildMetrics', buildWaitTime?: number | null, buildQueueTime?: number | null, buildDuration?: number | null } | null }, deprecationInfo?: { __typename?: 'EASBuildDeprecationInfo', type: EasBuildDeprecationInfoType, message: string } | null } } };
export type CreateIosBuildMutation = { __typename?: 'RootMutation', build: { __typename?: 'BuildMutation', createIosBuild: { __typename?: 'CreateBuildResult', build: { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, gitCommitMessage?: string | null, initialQueuePosition?: number | null, queuePosition?: number | null, estimatedWaitTimeLeftSeconds?: number | null, priority: BuildPriority, createdAt: any, updatedAt: any, message?: string | null, completedAt?: any | null, expirationDate?: any | null, isForIosSimulator: boolean, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null, applicationArchiveUrl?: string | null, buildArtifactsUrl?: string | null } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'SSOUser', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string }, metrics?: { __typename?: 'BuildMetrics', buildWaitTime?: number | null, buildQueueTime?: number | null, buildDuration?: number | null } | null }, deprecationInfo?: { __typename?: 'EASBuildDeprecationInfo', type: EasBuildDeprecationInfoType, message: string } | null } } };
export type UpdateBuildMetadataMutationVariables = Exact<{
buildId: Scalars['ID']['input'];
@@ -9669,7 +9625,7 @@ export type UpdateBuildMetadataMutationVariables = Exact<{
}>;
export type UpdateBuildMetadataMutation = { __typename?: 'RootMutation', build: { __typename?: 'BuildMutation', updateBuildMetadata: { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, gitCommitMessage?: string | null, initialQueuePosition?: number | null, queuePosition?: number | null, estimatedWaitTimeLeftSeconds?: number | null, priority: BuildPriority, createdAt: any, updatedAt: any, message?: string | null, completedAt?: any | null, expirationDate?: any | null, isForIosSimulator: boolean, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null, applicationArchiveUrl?: string | null, buildArtifactsUrl?: string | null } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'SSOUser', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string }, metrics?: { __typename?: 'BuildMetrics', buildWaitTime?: number | null, buildQueueTime?: number | null, buildDuration?: number | null } | null } } };
export type UpdateBuildMetadataMutation = { __typename?: 'RootMutation', build: { __typename?: 'BuildMutation', updateBuildMetadata: { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, gitCommitMessage?: string | null, initialQueuePosition?: number | null, queuePosition?: number | null, estimatedWaitTimeLeftSeconds?: number | null, priority: BuildPriority, createdAt: any, updatedAt: any, message?: string | null, completedAt?: any | null, expirationDate?: any | null, isForIosSimulator: boolean, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null, applicationArchiveUrl?: string | null, buildArtifactsUrl?: string | null } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'SSOUser', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string }, metrics?: { __typename?: 'BuildMetrics', buildWaitTime?: number | null, buildQueueTime?: number | null, buildDuration?: number | null } | null } } };
export type RetryIosBuildMutationVariables = Exact<{
buildId: Scalars['ID']['input'];
@@ -9677,7 +9633,7 @@ export type RetryIosBuildMutationVariables = Exact<{
}>;
export type RetryIosBuildMutation = { __typename?: 'RootMutation', build: { __typename?: 'BuildMutation', retryIosBuild: { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, gitCommitMessage?: string | null, initialQueuePosition?: number | null, queuePosition?: number | null, estimatedWaitTimeLeftSeconds?: number | null, priority: BuildPriority, createdAt: any, updatedAt: any, message?: string | null, completedAt?: any | null, expirationDate?: any | null, isForIosSimulator: boolean, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null, applicationArchiveUrl?: string | null, buildArtifactsUrl?: string | null } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'SSOUser', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string }, metrics?: { __typename?: 'BuildMetrics', buildWaitTime?: number | null, buildQueueTime?: number | null, buildDuration?: number | null } | null } } };
export type RetryIosBuildMutation = { __typename?: 'RootMutation', build: { __typename?: 'BuildMutation', retryIosBuild: { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, gitCommitMessage?: string | null, initialQueuePosition?: number | null, queuePosition?: number | null, estimatedWaitTimeLeftSeconds?: number | null, priority: BuildPriority, createdAt: any, updatedAt: any, message?: string | null, completedAt?: any | null, expirationDate?: any | null, isForIosSimulator: boolean, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null, applicationArchiveUrl?: string | null, buildArtifactsUrl?: string | null } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'SSOUser', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string }, metrics?: { __typename?: 'BuildMetrics', buildWaitTime?: number | null, buildQueueTime?: number | null, buildDuration?: number | null } | null } } };
export type CreateEnvironmentSecretForAccountMutationVariables = Exact<{
input: CreateEnvironmentSecretInput;
@@ -9708,7 +9664,7 @@ export type CreateEnvironmentVariableForAccountMutationVariables = Exact<{
}>;
export type CreateEnvironmentVariableForAccountMutation = { __typename?: 'RootMutation', environmentVariable: { __typename?: 'EnvironmentVariableMutation', createEnvironmentVariableForAccount: { __typename?: 'EnvironmentVariable', id: string, name: string, value?: string | null, environments?: Array<any> | null, createdAt: any, updatedAt: any, scope: EnvironmentVariableScope, visibility?: EnvironmentVariableVisibility | null, type: EnvironmentSecretType } } };
export type CreateEnvironmentVariableForAccountMutation = { __typename?: 'RootMutation', environmentVariable: { __typename?: 'EnvironmentVariableMutation', createEnvironmentVariableForAccount: { __typename?: 'EnvironmentVariable', id: string, name: string, value?: string | null, environments?: Array<EnvironmentVariableEnvironment> | null, createdAt: any, updatedAt: any, scope: EnvironmentVariableScope, visibility?: EnvironmentVariableVisibility | null, type: EnvironmentSecretType } } };
export type CreateEnvironmentVariableForAppMutationVariables = Exact<{
input: CreateEnvironmentVariableInput;
@@ -9716,14 +9672,14 @@ export type CreateEnvironmentVariableForAppMutationVariables = Exact<{
}>;
export type CreateEnvironmentVariableForAppMutation = { __typename?: 'RootMutation', environmentVariable: { __typename?: 'EnvironmentVariableMutation', createEnvironmentVariableForApp: { __typename?: 'EnvironmentVariable', id: string, name: string, value?: string | null, environments?: Array<any> | null, createdAt: any, updatedAt: any, scope: EnvironmentVariableScope, visibility?: EnvironmentVariableVisibility | null, type: EnvironmentSecretType } } };
export type CreateEnvironmentVariableForAppMutation = { __typename?: 'RootMutation', environmentVariable: { __typename?: 'EnvironmentVariableMutation', createEnvironmentVariableForApp: { __typename?: 'EnvironmentVariable', id: string, name: string, value?: string | null, environments?: Array<EnvironmentVariableEnvironment> | null, createdAt: any, updatedAt: any, scope: EnvironmentVariableScope, visibility?: EnvironmentVariableVisibility | null, type: EnvironmentSecretType } } };
export type UpdateEnvironmentVariableMutationVariables = Exact<{
input: UpdateEnvironmentVariableInput;
}>;
export type UpdateEnvironmentVariableMutation = { __typename?: 'RootMutation', environmentVariable: { __typename?: 'EnvironmentVariableMutation', updateEnvironmentVariable: { __typename?: 'EnvironmentVariable', id: string, name: string, value?: string | null, environments?: Array<any> | null, createdAt: any, updatedAt: any, scope: EnvironmentVariableScope, visibility?: EnvironmentVariableVisibility | null, type: EnvironmentSecretType } } };
export type UpdateEnvironmentVariableMutation = { __typename?: 'RootMutation', environmentVariable: { __typename?: 'EnvironmentVariableMutation', updateEnvironmentVariable: { __typename?: 'EnvironmentVariable', id: string, name: string, value?: string | null, environments?: Array<EnvironmentVariableEnvironment> | null, createdAt: any, updatedAt: any, scope: EnvironmentVariableScope, visibility?: EnvironmentVariableVisibility | null, type: EnvironmentSecretType } } };
export type DeleteEnvironmentVariableMutationVariables = Exact<{
id: Scalars['ID']['input'];
@@ -9761,7 +9717,7 @@ export type CreateLocalBuildMutationVariables = Exact<{
}>;
export type CreateLocalBuildMutation = { __typename?: 'RootMutation', build: { __typename?: 'BuildMutation', createLocalBuild: { __typename?: 'CreateBuildResult', build: { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, gitCommitMessage?: string | null, initialQueuePosition?: number | null, queuePosition?: number | null, estimatedWaitTimeLeftSeconds?: number | null, priority: BuildPriority, createdAt: any, updatedAt: any, message?: string | null, completedAt?: any | null, expirationDate?: any | null, isForIosSimulator: boolean, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null, applicationArchiveUrl?: string | null, buildArtifactsUrl?: string | null } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'SSOUser', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string }, metrics?: { __typename?: 'BuildMetrics', buildWaitTime?: number | null, buildQueueTime?: number | null, buildDuration?: number | null } | null } } } };
export type CreateLocalBuildMutation = { __typename?: 'RootMutation', build: { __typename?: 'BuildMutation', createLocalBuild: { __typename?: 'CreateBuildResult', build: { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, gitCommitMessage?: string | null, initialQueuePosition?: number | null, queuePosition?: number | null, estimatedWaitTimeLeftSeconds?: number | null, priority: BuildPriority, createdAt: any, updatedAt: any, message?: string | null, completedAt?: any | null, expirationDate?: any | null, isForIosSimulator: boolean, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null, applicationArchiveUrl?: string | null, buildArtifactsUrl?: string | null } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'SSOUser', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string }, metrics?: { __typename?: 'BuildMetrics', buildWaitTime?: number | null, buildQueueTime?: number | null, buildDuration?: number | null } | null } } } };
export type GetSignedUploadMutationVariables = Exact<{
contentTypes: Array<Scalars['String']['input']> | Scalars['String']['input'];
@@ -9775,7 +9731,7 @@ export type UpdatePublishMutationVariables = Exact<{
}>;
export type UpdatePublishMutation = { __typename?: 'RootMutation', updateBranch: { __typename?: 'UpdateBranchMutation', publishUpdateGroups: Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: any | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string, group: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }> } };
export type UpdatePublishMutation = { __typename?: 'RootMutation', updateBranch: { __typename?: 'UpdateBranchMutation', publishUpdateGroups: Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: EnvironmentVariableEnvironment | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string, group: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }> } };
export type SetCodeSigningInfoMutationVariables = Exact<{
updateId: Scalars['ID']['input'];
@@ -9791,7 +9747,7 @@ export type SetRolloutPercentageMutationVariables = Exact<{
}>;
export type SetRolloutPercentageMutation = { __typename?: 'RootMutation', update: { __typename?: 'UpdateMutation', setRolloutPercentage: { __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: any | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string, group: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null } } };
export type SetRolloutPercentageMutation = { __typename?: 'RootMutation', update: { __typename?: 'UpdateMutation', setRolloutPercentage: { __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: EnvironmentVariableEnvironment | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string, group: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null } } };
export type CreateAndroidSubmissionMutationVariables = Exact<{
appId: Scalars['ID']['input'];
@@ -9801,7 +9757,7 @@ export type CreateAndroidSubmissionMutationVariables = Exact<{
}>;
export type CreateAndroidSubmissionMutation = { __typename?: 'RootMutation', submission: { __typename?: 'SubmissionMutation', createAndroidSubmission: { __typename?: 'CreateSubmissionResult', submission: { __typename?: 'Submission', id: string, status: SubmissionStatus, platform: AppPlatform, logFiles: Array<string>, app: { __typename?: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } }, androidConfig?: { __typename?: 'AndroidSubmissionConfig', applicationIdentifier?: string | null, track: string, releaseStatus?: SubmissionAndroidReleaseStatus | null, rollout?: number | null } | null, iosConfig?: { __typename?: 'IosSubmissionConfig', ascAppIdentifier: string, appleIdUsername?: string | null } | null, error?: { __typename?: 'SubmissionError', errorCode?: string | null, message?: string | null } | null } } } };
export type CreateAndroidSubmissionMutation = { __typename?: 'RootMutation', submission: { __typename?: 'SubmissionMutation', createAndroidSubmission: { __typename?: 'CreateSubmissionResult', submission: { __typename?: 'Submission', id: string, status: SubmissionStatus, platform: AppPlatform, logFiles: Array<string>, app: { __typename?: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } }, androidConfig?: { __typename?: 'AndroidSubmissionConfig', applicationIdentifier?: string | null, track: SubmissionAndroidTrack, releaseStatus?: SubmissionAndroidReleaseStatus | null, rollout?: number | null } | null, iosConfig?: { __typename?: 'IosSubmissionConfig', ascAppIdentifier: string, appleIdUsername?: string | null } | null, error?: { __typename?: 'SubmissionError', errorCode?: string | null, message?: string | null } | null } } } };
export type CreateIosSubmissionMutationVariables = Exact<{
appId: Scalars['ID']['input'];
@@ -9811,7 +9767,7 @@ export type CreateIosSubmissionMutationVariables = Exact<{
}>;
export type CreateIosSubmissionMutation = { __typename?: 'RootMutation', submission: { __typename?: 'SubmissionMutation', createIosSubmission: { __typename?: 'CreateSubmissionResult', submission: { __typename?: 'Submission', id: string, status: SubmissionStatus, platform: AppPlatform, logFiles: Array<string>, app: { __typename?: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } }, androidConfig?: { __typename?: 'AndroidSubmissionConfig', applicationIdentifier?: string | null, track: string, releaseStatus?: SubmissionAndroidReleaseStatus | null, rollout?: number | null } | null, iosConfig?: { __typename?: 'IosSubmissionConfig', ascAppIdentifier: string, appleIdUsername?: string | null } | null, error?: { __typename?: 'SubmissionError', errorCode?: string | null, message?: string | null } | null } } } };
export type CreateIosSubmissionMutation = { __typename?: 'RootMutation', submission: { __typename?: 'SubmissionMutation', createIosSubmission: { __typename?: 'CreateSubmissionResult', submission: { __typename?: 'Submission', id: string, status: SubmissionStatus, platform: AppPlatform, logFiles: Array<string>, app: { __typename?: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } }, androidConfig?: { __typename?: 'AndroidSubmissionConfig', applicationIdentifier?: string | null, track: SubmissionAndroidTrack, releaseStatus?: SubmissionAndroidReleaseStatus | null, rollout?: number | null } | null, iosConfig?: { __typename?: 'IosSubmissionConfig', ascAppIdentifier: string, appleIdUsername?: string | null } | null, error?: { __typename?: 'SubmissionError', errorCode?: string | null, message?: string | null } | null } } } };
export type CreateUploadSessionMutationVariables = Exact<{
type: UploadSessionType;
@@ -9961,7 +9917,7 @@ export type BranchesByAppQueryVariables = Exact<{
}>;
export type BranchesByAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateBranches: Array<{ __typename?: 'UpdateBranch', id: string, name: string, updates: Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: any | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string, group: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }> }> } } };
export type BranchesByAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateBranches: Array<{ __typename?: 'UpdateBranch', id: string, name: string, updates: Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: EnvironmentVariableEnvironment | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string, group: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }> }> } } };
export type BranchesBasicPaginatedOnAppQueryVariables = Exact<{
appId: Scalars['String']['input'];
@@ -9982,21 +9938,21 @@ export type ViewBranchesOnUpdateChannelQueryVariables = Exact<{
}>;
export type ViewBranchesOnUpdateChannelQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateChannelByName?: { __typename?: 'UpdateChannel', id: string, updateBranches: Array<{ __typename?: 'UpdateBranch', id: string, name: string, updateGroups: Array<Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: any | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string, group: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }>> }> } | null } } };
export type ViewBranchesOnUpdateChannelQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateChannelByName?: { __typename?: 'UpdateChannel', id: string, updateBranches: Array<{ __typename?: 'UpdateBranch', id: string, name: string, updateGroups: Array<Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: EnvironmentVariableEnvironment | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string, group: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }>> }> } | null } } };
export type BuildsByIdQueryVariables = Exact<{
buildId: Scalars['ID']['input'];
}>;
export type BuildsByIdQuery = { __typename?: 'RootQuery', builds: { __typename?: 'BuildQuery', byId: { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, gitCommitMessage?: string | null, initialQueuePosition?: number | null, queuePosition?: number | null, estimatedWaitTimeLeftSeconds?: number | null, priority: BuildPriority, createdAt: any, updatedAt: any, message?: string | null, completedAt?: any | null, expirationDate?: any | null, isForIosSimulator: boolean, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null, applicationArchiveUrl?: string | null, buildArtifactsUrl?: string | null } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'SSOUser', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string }, metrics?: { __typename?: 'BuildMetrics', buildWaitTime?: number | null, buildQueueTime?: number | null, buildDuration?: number | null } | null } } };
export type BuildsByIdQuery = { __typename?: 'RootQuery', builds: { __typename?: 'BuildQuery', byId: { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, gitCommitMessage?: string | null, initialQueuePosition?: number | null, queuePosition?: number | null, estimatedWaitTimeLeftSeconds?: number | null, priority: BuildPriority, createdAt: any, updatedAt: any, message?: string | null, completedAt?: any | null, expirationDate?: any | null, isForIosSimulator: boolean, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null, applicationArchiveUrl?: string | null, buildArtifactsUrl?: string | null } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'SSOUser', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string }, metrics?: { __typename?: 'BuildMetrics', buildWaitTime?: number | null, buildQueueTime?: number | null, buildDuration?: number | null } | null } } };
export type BuildsWithSubmissionsByIdQueryVariables = Exact<{
buildId: Scalars['ID']['input'];
}>;
export type BuildsWithSubmissionsByIdQuery = { __typename?: 'RootQuery', builds: { __typename?: 'BuildQuery', byId: { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, gitCommitMessage?: string | null, initialQueuePosition?: number | null, queuePosition?: number | null, estimatedWaitTimeLeftSeconds?: number | null, priority: BuildPriority, createdAt: any, updatedAt: any, message?: string | null, completedAt?: any | null, expirationDate?: any | null, isForIosSimulator: boolean, submissions: Array<{ __typename?: 'Submission', id: string, status: SubmissionStatus, platform: AppPlatform, logFiles: Array<string>, app: { __typename?: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } }, androidConfig?: { __typename?: 'AndroidSubmissionConfig', applicationIdentifier?: string | null, track: string, releaseStatus?: SubmissionAndroidReleaseStatus | null, rollout?: number | null } | null, iosConfig?: { __typename?: 'IosSubmissionConfig', ascAppIdentifier: string, appleIdUsername?: string | null } | null, error?: { __typename?: 'SubmissionError', errorCode?: string | null, message?: string | null } | null }>, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null, applicationArchiveUrl?: string | null, buildArtifactsUrl?: string | null } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'SSOUser', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string }, metrics?: { __typename?: 'BuildMetrics', buildWaitTime?: number | null, buildQueueTime?: number | null, buildDuration?: number | null } | null } } };
export type BuildsWithSubmissionsByIdQuery = { __typename?: 'RootQuery', builds: { __typename?: 'BuildQuery', byId: { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, gitCommitMessage?: string | null, initialQueuePosition?: number | null, queuePosition?: number | null, estimatedWaitTimeLeftSeconds?: number | null, priority: BuildPriority, createdAt: any, updatedAt: any, message?: string | null, completedAt?: any | null, expirationDate?: any | null, isForIosSimulator: boolean, submissions: Array<{ __typename?: 'Submission', id: string, status: SubmissionStatus, platform: AppPlatform, logFiles: Array<string>, app: { __typename?: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } }, androidConfig?: { __typename?: 'AndroidSubmissionConfig', applicationIdentifier?: string | null, track: SubmissionAndroidTrack, releaseStatus?: SubmissionAndroidReleaseStatus | null, rollout?: number | null } | null, iosConfig?: { __typename?: 'IosSubmissionConfig', ascAppIdentifier: string, appleIdUsername?: string | null } | null, error?: { __typename?: 'SubmissionError', errorCode?: string | null, message?: string | null } | null }>, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null, applicationArchiveUrl?: string | null, buildArtifactsUrl?: string | null } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'SSOUser', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string }, metrics?: { __typename?: 'BuildMetrics', buildWaitTime?: number | null, buildQueueTime?: number | null, buildDuration?: number | null } | null } } };
export type BuildsWithFingerprintByIdQueryVariables = Exact<{
buildId: Scalars['ID']['input'];
@@ -10013,7 +9969,7 @@ export type ViewBuildsOnAppQueryVariables = Exact<{
}>;
export type ViewBuildsOnAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, builds: Array<{ __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, gitCommitMessage?: string | null, initialQueuePosition?: number | null, queuePosition?: number | null, estimatedWaitTimeLeftSeconds?: number | null, priority: BuildPriority, createdAt: any, updatedAt: any, message?: string | null, completedAt?: any | null, expirationDate?: any | null, isForIosSimulator: boolean, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null, applicationArchiveUrl?: string | null, buildArtifactsUrl?: string | null } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'SSOUser', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string }, metrics?: { __typename?: 'BuildMetrics', buildWaitTime?: number | null, buildQueueTime?: number | null, buildDuration?: number | null } | null }> } } };
export type ViewBuildsOnAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, builds: Array<{ __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, gitCommitMessage?: string | null, initialQueuePosition?: number | null, queuePosition?: number | null, estimatedWaitTimeLeftSeconds?: number | null, priority: BuildPriority, createdAt: any, updatedAt: any, message?: string | null, completedAt?: any | null, expirationDate?: any | null, isForIosSimulator: boolean, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null, applicationArchiveUrl?: string | null, buildArtifactsUrl?: string | null } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'SSOUser', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string }, metrics?: { __typename?: 'BuildMetrics', buildWaitTime?: number | null, buildQueueTime?: number | null, buildDuration?: number | null } | null }> } } };
export type ViewUpdateChannelBasicInfoOnAppQueryVariables = Exact<{
appId: Scalars['String']['input'];
@@ -10030,7 +9986,7 @@ export type ViewUpdateChannelOnAppQueryVariables = Exact<{
}>;
export type ViewUpdateChannelOnAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateChannelByName?: { __typename?: 'UpdateChannel', id: string, isPaused: boolean, name: string, updatedAt: any, createdAt: any, branchMapping: string, updateBranches: Array<{ __typename?: 'UpdateBranch', id: string, name: string, updateGroups: Array<Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: any | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string, group: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }>> }> } | null } } };
export type ViewUpdateChannelOnAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateChannelByName?: { __typename?: 'UpdateChannel', id: string, isPaused: boolean, name: string, updatedAt: any, createdAt: any, branchMapping: string, updateBranches: Array<{ __typename?: 'UpdateBranch', id: string, name: string, updateGroups: Array<Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: EnvironmentVariableEnvironment | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string, group: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }>> }> } | null } } };
export type ViewUpdateChannelsOnAppQueryVariables = Exact<{
appId: Scalars['String']['input'];
@@ -10039,7 +9995,7 @@ export type ViewUpdateChannelsOnAppQueryVariables = Exact<{
}>;
export type ViewUpdateChannelsOnAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateChannels: Array<{ __typename?: 'UpdateChannel', id: string, isPaused: boolean, name: string, updatedAt: any, createdAt: any, branchMapping: string, updateBranches: Array<{ __typename?: 'UpdateBranch', id: string, name: string, updateGroups: Array<Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: any | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string, group: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }>> }> }> } } };
export type ViewUpdateChannelsOnAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateChannels: Array<{ __typename?: 'UpdateChannel', id: string, isPaused: boolean, name: string, updatedAt: any, createdAt: any, branchMapping: string, updateBranches: Array<{ __typename?: 'UpdateBranch', id: string, name: string, updateGroups: Array<Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: EnvironmentVariableEnvironment | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string, group: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }>> }> }> } } };
export type ViewUpdateChannelsPaginatedOnAppQueryVariables = Exact<{
appId: Scalars['String']['input'];
@@ -10062,42 +10018,42 @@ export type EnvironmentSecretsByAppIdQuery = { __typename?: 'RootQuery', app: {
export type EnvironmentVariablesIncludingSensitiveByAppIdQueryVariables = Exact<{
appId: Scalars['String']['input'];
filterNames?: InputMaybe<Array<Scalars['String']['input']> | Scalars['String']['input']>;
environment?: InputMaybe<Scalars['EnvironmentVariableEnvironment']['input']>;
environment?: InputMaybe<EnvironmentVariableEnvironment>;
includeFileContent: Scalars['Boolean']['input'];
}>;
export type EnvironmentVariablesIncludingSensitiveByAppIdQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, environmentVariablesIncludingSensitive: Array<{ __typename?: 'EnvironmentVariableWithSecret', id: string, name: string, value?: string | null, environments?: Array<any> | null, createdAt: any, updatedAt: any, scope: EnvironmentVariableScope, visibility: EnvironmentVariableVisibility, type: EnvironmentSecretType, valueWithFileContent?: string | null }> } } };
export type EnvironmentVariablesIncludingSensitiveByAppIdQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, environmentVariablesIncludingSensitive: Array<{ __typename?: 'EnvironmentVariableWithSecret', id: string, name: string, value?: string | null, environments?: Array<EnvironmentVariableEnvironment> | null, createdAt: any, updatedAt: any, scope: EnvironmentVariableScope, visibility: EnvironmentVariableVisibility, type: EnvironmentSecretType, valueWithFileContent?: string | null }> } } };
export type EnvironmentVariablesByAppIdQueryVariables = Exact<{
appId: Scalars['String']['input'];
filterNames?: InputMaybe<Array<Scalars['String']['input']> | Scalars['String']['input']>;
environment?: InputMaybe<Scalars['EnvironmentVariableEnvironment']['input']>;
environment?: InputMaybe<EnvironmentVariableEnvironment>;
includeFileContent: Scalars['Boolean']['input'];
}>;
export type EnvironmentVariablesByAppIdQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, environmentVariables: Array<{ __typename?: 'EnvironmentVariable', id: string, linkedEnvironments?: Array<any> | null, name: string, value?: string | null, environments?: Array<any> | null, createdAt: any, updatedAt: any, scope: EnvironmentVariableScope, visibility?: EnvironmentVariableVisibility | null, type: EnvironmentSecretType, valueWithFileContent?: string | null }> } } };
export type EnvironmentVariablesByAppIdQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, environmentVariables: Array<{ __typename?: 'EnvironmentVariable', id: string, linkedEnvironments?: Array<EnvironmentVariableEnvironment> | null, name: string, value?: string | null, environments?: Array<EnvironmentVariableEnvironment> | null, createdAt: any, updatedAt: any, scope: EnvironmentVariableScope, visibility?: EnvironmentVariableVisibility | null, type: EnvironmentSecretType, valueWithFileContent?: string | null }> } } };
export type EnvironmentVariablesSharedQueryVariables = Exact<{
appId: Scalars['String']['input'];
filterNames?: InputMaybe<Array<Scalars['String']['input']> | Scalars['String']['input']>;
environment?: InputMaybe<Scalars['EnvironmentVariableEnvironment']['input']>;
environment?: InputMaybe<EnvironmentVariableEnvironment>;
includeFileContent: Scalars['Boolean']['input'];
}>;
export type EnvironmentVariablesSharedQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, ownerAccount: { __typename?: 'Account', id: string, environmentVariables: Array<{ __typename?: 'EnvironmentVariable', id: string, linkedEnvironments?: Array<any> | null, name: string, value?: string | null, environments?: Array<any> | null, createdAt: any, updatedAt: any, scope: EnvironmentVariableScope, visibility?: EnvironmentVariableVisibility | null, type: EnvironmentSecretType, valueWithFileContent?: string | null }> } } } };
export type EnvironmentVariablesSharedQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, ownerAccount: { __typename?: 'Account', id: string, environmentVariables: Array<{ __typename?: 'EnvironmentVariable', id: string, linkedEnvironments?: Array<EnvironmentVariableEnvironment> | null, name: string, value?: string | null, environments?: Array<EnvironmentVariableEnvironment> | null, createdAt: any, updatedAt: any, scope: EnvironmentVariableScope, visibility?: EnvironmentVariableVisibility | null, type: EnvironmentSecretType, valueWithFileContent?: string | null }> } } } };
export type EnvironmentVariablesSharedWithSensitiveQueryVariables = Exact<{
appId: Scalars['String']['input'];
filterNames?: InputMaybe<Array<Scalars['String']['input']> | Scalars['String']['input']>;
environment?: InputMaybe<Scalars['EnvironmentVariableEnvironment']['input']>;
environment?: InputMaybe<EnvironmentVariableEnvironment>;
includeFileContent: Scalars['Boolean']['input'];
}>;
export type EnvironmentVariablesSharedWithSensitiveQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, ownerAccount: { __typename?: 'Account', id: string, environmentVariablesIncludingSensitive: Array<{ __typename?: 'EnvironmentVariableWithSecret', id: string, name: string, value?: string | null, environments?: Array<any> | null, createdAt: any, updatedAt: any, scope: EnvironmentVariableScope, visibility: EnvironmentVariableVisibility, type: EnvironmentSecretType, valueWithFileContent?: string | null }> } } } };
export type EnvironmentVariablesSharedWithSensitiveQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, ownerAccount: { __typename?: 'Account', id: string, environmentVariablesIncludingSensitive: Array<{ __typename?: 'EnvironmentVariableWithSecret', id: string, name: string, value?: string | null, environments?: Array<EnvironmentVariableEnvironment> | null, createdAt: any, updatedAt: any, scope: EnvironmentVariableScope, visibility: EnvironmentVariableVisibility, type: EnvironmentSecretType, valueWithFileContent?: string | null }> } } } };
export type FingerprintsByAppIdQueryVariables = Exact<{
appId: Scalars['String']['input'];
@@ -10157,7 +10113,7 @@ export type SubmissionsByIdQueryVariables = Exact<{
}>;
export type SubmissionsByIdQuery = { __typename?: 'RootQuery', submissions: { __typename?: 'SubmissionQuery', byId: { __typename?: 'Submission', id: string, status: SubmissionStatus, platform: AppPlatform, logFiles: Array<string>, app: { __typename?: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } }, androidConfig?: { __typename?: 'AndroidSubmissionConfig', applicationIdentifier?: string | null, track: string, releaseStatus?: SubmissionAndroidReleaseStatus | null, rollout?: number | null } | null, iosConfig?: { __typename?: 'IosSubmissionConfig', ascAppIdentifier: string, appleIdUsername?: string | null } | null, error?: { __typename?: 'SubmissionError', errorCode?: string | null, message?: string | null } | null } } };
export type SubmissionsByIdQuery = { __typename?: 'RootQuery', submissions: { __typename?: 'SubmissionQuery', byId: { __typename?: 'Submission', id: string, status: SubmissionStatus, platform: AppPlatform, logFiles: Array<string>, app: { __typename?: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } }, androidConfig?: { __typename?: 'AndroidSubmissionConfig', applicationIdentifier?: string | null, track: SubmissionAndroidTrack, releaseStatus?: SubmissionAndroidReleaseStatus | null, rollout?: number | null } | null, iosConfig?: { __typename?: 'IosSubmissionConfig', ascAppIdentifier: string, appleIdUsername?: string | null } | null, error?: { __typename?: 'SubmissionError', errorCode?: string | null, message?: string | null } | null } } };
export type GetAllSubmissionsForAppQueryVariables = Exact<{
appId: Scalars['String']['input'];
@@ -10168,14 +10124,14 @@ export type GetAllSubmissionsForAppQueryVariables = Exact<{
}>;
export type GetAllSubmissionsForAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, submissions: Array<{ __typename?: 'Submission', id: string, status: SubmissionStatus, platform: AppPlatform, logFiles: Array<string>, app: { __typename?: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } }, androidConfig?: { __typename?: 'AndroidSubmissionConfig', applicationIdentifier?: string | null, track: string, releaseStatus?: SubmissionAndroidReleaseStatus | null, rollout?: number | null } | null, iosConfig?: { __typename?: 'IosSubmissionConfig', ascAppIdentifier: string, appleIdUsername?: string | null } | null, error?: { __typename?: 'SubmissionError', errorCode?: string | null, message?: string | null } | null }> } } };
export type GetAllSubmissionsForAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, submissions: Array<{ __typename?: 'Submission', id: string, status: SubmissionStatus, platform: AppPlatform, logFiles: Array<string>, app: { __typename?: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } }, androidConfig?: { __typename?: 'AndroidSubmissionConfig', applicationIdentifier?: string | null, track: SubmissionAndroidTrack, releaseStatus?: SubmissionAndroidReleaseStatus | null, rollout?: number | null } | null, iosConfig?: { __typename?: 'IosSubmissionConfig', ascAppIdentifier: string, appleIdUsername?: string | null } | null, error?: { __typename?: 'SubmissionError', errorCode?: string | null, message?: string | null } | null }> } } };
export type ViewUpdatesByGroupQueryVariables = Exact<{
groupId: Scalars['ID']['input'];
}>;
export type ViewUpdatesByGroupQuery = { __typename?: 'RootQuery', updatesByGroup: Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: any | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string, group: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }> };
export type ViewUpdatesByGroupQuery = { __typename?: 'RootQuery', updatesByGroup: Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: EnvironmentVariableEnvironment | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string, group: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }> };
export type ViewUpdateGroupsOnBranchQueryVariables = Exact<{
appId: Scalars['String']['input'];
@@ -10186,7 +10142,7 @@ export type ViewUpdateGroupsOnBranchQueryVariables = Exact<{
}>;
export type ViewUpdateGroupsOnBranchQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateBranchByName?: { __typename?: 'UpdateBranch', id: string, updateGroups: Array<Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: any | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string, group: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }>> } | null } } };
export type ViewUpdateGroupsOnBranchQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateBranchByName?: { __typename?: 'UpdateBranch', id: string, updateGroups: Array<Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: EnvironmentVariableEnvironment | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string, group: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }>> } | null } } };
export type ViewUpdateGroupsOnAppQueryVariables = Exact<{
appId: Scalars['String']['input'];
@@ -10196,14 +10152,14 @@ export type ViewUpdateGroupsOnAppQueryVariables = Exact<{
}>;
export type ViewUpdateGroupsOnAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateGroups: Array<Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: any | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string, group: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }>> } } };
export type ViewUpdateGroupsOnAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateGroups: Array<Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: EnvironmentVariableEnvironment | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string, group: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }>> } } };
export type UpdateByIdQueryVariables = Exact<{
updateId: Scalars['ID']['input'];
}>;
export type UpdateByIdQuery = { __typename?: 'RootQuery', updates: { __typename?: 'UpdateQuery', byId: { __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: any | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string, group: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null } } };
export type UpdateByIdQuery = { __typename?: 'RootQuery', updates: { __typename?: 'UpdateQuery', byId: { __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: EnvironmentVariableEnvironment | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string, group: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null } } };
export type CurrentUserQueryVariables = Exact<{ [key: string]: never; }>;
@@ -10230,7 +10186,7 @@ export type WorkflowJobByIdQueryVariables = Exact<{
}>;
export type WorkflowJobByIdQuery = { __typename?: 'RootQuery', workflowJobs: { __typename?: 'WorkflowJobQuery', byId: { __typename?: 'WorkflowJob', id: string, key: string, name: string, status: WorkflowJobStatus, type: WorkflowJobType, outputs: any, createdAt: any, updatedAt: any, workflowRun: { __typename?: 'WorkflowRun', id: string }, turtleJobRun?: { __typename?: 'JobRun', id: string, logFileUrls: Array<string>, artifacts: Array<{ __typename?: 'WorkflowArtifact', id: string, name: string, contentType?: string | null, fileSizeBytes?: number | null, filename: string, downloadUrl?: string | null }>, errors: Array<{ __typename?: 'JobRunError', errorCode: string, message: string }> } | null, turtleBuild?: { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, gitCommitMessage?: string | null, initialQueuePosition?: number | null, queuePosition?: number | null, estimatedWaitTimeLeftSeconds?: number | null, priority: BuildPriority, createdAt: any, updatedAt: any, message?: string | null, completedAt?: any | null, expirationDate?: any | null, isForIosSimulator: boolean, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null, applicationArchiveUrl?: string | null, buildArtifactsUrl?: string | null } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'SSOUser', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string }, metrics?: { __typename?: 'BuildMetrics', buildWaitTime?: number | null, buildQueueTime?: number | null, buildDuration?: number | null } | null } | null, errors: Array<{ __typename?: 'WorkflowJobError', title: string, message: string }> } } };
export type WorkflowJobByIdQuery = { __typename?: 'RootQuery', workflowJobs: { __typename?: 'WorkflowJobQuery', byId: { __typename?: 'WorkflowJob', id: string, key: string, name: string, status: WorkflowJobStatus, type: WorkflowJobType, outputs: any, createdAt: any, updatedAt: any, workflowRun: { __typename?: 'WorkflowRun', id: string }, turtleJobRun?: { __typename?: 'JobRun', id: string, logFileUrls: Array<string>, errors: Array<{ __typename?: 'JobRunError', errorCode: string, message: string }> } | null, errors: Array<{ __typename?: 'WorkflowJobError', title: string, message: string }> } } };
export type WorkflowRunByIdQueryVariables = Exact<{
workflowRunId: Scalars['ID']['input'];
@@ -10244,7 +10200,7 @@ export type WorkflowRunByIdWithJobsQueryVariables = Exact<{
}>;
export type WorkflowRunByIdWithJobsQuery = { __typename?: 'RootQuery', workflowRuns: { __typename?: 'WorkflowRunQuery', byId: { __typename?: 'WorkflowRun', id: string, status: WorkflowRunStatus, gitCommitMessage?: string | null, gitCommitHash?: string | null, requestedGitRef?: string | null, triggeringLabelName?: string | null, triggerEventType: WorkflowRunTriggerEventType, triggeringSchedule?: string | null, createdAt: any, updatedAt: any, workflow: { __typename?: 'Workflow', id: string, name?: string | null, fileName: string, app: { __typename?: 'App', id: string, name: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } }, jobs: Array<{ __typename?: 'WorkflowJob', id: string, key: string, name: string, status: WorkflowJobStatus, type: WorkflowJobType, outputs: any, createdAt: any, updatedAt: any, workflowRun: { __typename?: 'WorkflowRun', id: string }, turtleJobRun?: { __typename?: 'JobRun', id: string, logFileUrls: Array<string>, artifacts: Array<{ __typename?: 'WorkflowArtifact', id: string, name: string, contentType?: string | null, fileSizeBytes?: number | null, filename: string, downloadUrl?: string | null }>, errors: Array<{ __typename?: 'JobRunError', errorCode: string, message: string }> } | null, turtleBuild?: { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, gitCommitMessage?: string | null, initialQueuePosition?: number | null, queuePosition?: number | null, estimatedWaitTimeLeftSeconds?: number | null, priority: BuildPriority, createdAt: any, updatedAt: any, message?: string | null, completedAt?: any | null, expirationDate?: any | null, isForIosSimulator: boolean, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null, applicationArchiveUrl?: string | null, buildArtifactsUrl?: string | null } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'SSOUser', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string }, metrics?: { __typename?: 'BuildMetrics', buildWaitTime?: number | null, buildQueueTime?: number | null, buildDuration?: number | null } | null } | null, errors: Array<{ __typename?: 'WorkflowJobError', title: string, message: string }> }>, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, errors: Array<{ __typename?: 'WorkflowRunError', title?: string | null, message: string }> } } };
export type WorkflowRunByIdWithJobsQuery = { __typename?: 'RootQuery', workflowRuns: { __typename?: 'WorkflowRunQuery', byId: { __typename?: 'WorkflowRun', id: string, status: WorkflowRunStatus, gitCommitMessage?: string | null, gitCommitHash?: string | null, requestedGitRef?: string | null, triggeringLabelName?: string | null, triggerEventType: WorkflowRunTriggerEventType, triggeringSchedule?: string | null, createdAt: any, updatedAt: any, workflow: { __typename?: 'Workflow', id: string, name?: string | null, fileName: string, app: { __typename?: 'App', id: string, name: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } }, jobs: Array<{ __typename?: 'WorkflowJob', id: string, key: string, name: string, status: WorkflowJobStatus, type: WorkflowJobType, outputs: any, createdAt: any, updatedAt: any, workflowRun: { __typename?: 'WorkflowRun', id: string }, turtleJobRun?: { __typename?: 'JobRun', id: string, logFileUrls: Array<string>, errors: Array<{ __typename?: 'JobRunError', errorCode: string, message: string }> } | null, errors: Array<{ __typename?: 'WorkflowJobError', title: string, message: string }> }>, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, errors: Array<{ __typename?: 'WorkflowRunError', title?: string | null, message: string }> } } };
export type WorkflowRunsForAppIdFileNameAndStatusQueryVariables = Exact<{
appId: Scalars['ID']['input'];
@@ -10262,17 +10218,17 @@ export type AppFragment = { __typename?: 'App', id: string, name: string, fullNa
export type BackgroundJobReceiptDataFragment = { __typename?: 'BackgroundJobReceipt', id: string, state: BackgroundJobState, tries: number, willRetry: boolean, resultId?: string | null, resultType: BackgroundJobResultType, resultData?: any | null, errorCode?: string | null, errorMessage?: string | null, createdAt: any, updatedAt: any };
export type BuildFragment = { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, gitCommitMessage?: string | null, initialQueuePosition?: number | null, queuePosition?: number | null, estimatedWaitTimeLeftSeconds?: number | null, priority: BuildPriority, createdAt: any, updatedAt: any, message?: string | null, completedAt?: any | null, expirationDate?: any | null, isForIosSimulator: boolean, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null, applicationArchiveUrl?: string | null, buildArtifactsUrl?: string | null } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'SSOUser', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string }, metrics?: { __typename?: 'BuildMetrics', buildWaitTime?: number | null, buildQueueTime?: number | null, buildDuration?: number | null } | null };
export type BuildFragment = { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, gitCommitMessage?: string | null, initialQueuePosition?: number | null, queuePosition?: number | null, estimatedWaitTimeLeftSeconds?: number | null, priority: BuildPriority, createdAt: any, updatedAt: any, message?: string | null, completedAt?: any | null, expirationDate?: any | null, isForIosSimulator: boolean, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null, applicationArchiveUrl?: string | null, buildArtifactsUrl?: string | null } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'SSOUser', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string }, metrics?: { __typename?: 'BuildMetrics', buildWaitTime?: number | null, buildQueueTime?: number | null, buildDuration?: number | null } | null };
export type BuildWithSubmissionsFragment = { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, gitCommitMessage?: string | null, initialQueuePosition?: number | null, queuePosition?: number | null, estimatedWaitTimeLeftSeconds?: number | null, priority: BuildPriority, createdAt: any, updatedAt: any, message?: string | null, completedAt?: any | null, expirationDate?: any | null, isForIosSimulator: boolean, submissions: Array<{ __typename?: 'Submission', id: string, status: SubmissionStatus, platform: AppPlatform, logFiles: Array<string>, app: { __typename?: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } }, androidConfig?: { __typename?: 'AndroidSubmissionConfig', applicationIdentifier?: string | null, track: string, releaseStatus?: SubmissionAndroidReleaseStatus | null, rollout?: number | null } | null, iosConfig?: { __typename?: 'IosSubmissionConfig', ascAppIdentifier: string, appleIdUsername?: string | null } | null, error?: { __typename?: 'SubmissionError', errorCode?: string | null, message?: string | null } | null }>, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null, applicationArchiveUrl?: string | null, buildArtifactsUrl?: string | null } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'SSOUser', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string }, metrics?: { __typename?: 'BuildMetrics', buildWaitTime?: number | null, buildQueueTime?: number | null, buildDuration?: number | null } | null };
export type BuildWithSubmissionsFragment = { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, gitCommitMessage?: string | null, initialQueuePosition?: number | null, queuePosition?: number | null, estimatedWaitTimeLeftSeconds?: number | null, priority: BuildPriority, createdAt: any, updatedAt: any, message?: string | null, completedAt?: any | null, expirationDate?: any | null, isForIosSimulator: boolean, submissions: Array<{ __typename?: 'Submission', id: string, status: SubmissionStatus, platform: AppPlatform, logFiles: Array<string>, app: { __typename?: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } }, androidConfig?: { __typename?: 'AndroidSubmissionConfig', applicationIdentifier?: string | null, track: SubmissionAndroidTrack, releaseStatus?: SubmissionAndroidReleaseStatus | null, rollout?: number | null } | null, iosConfig?: { __typename?: 'IosSubmissionConfig', ascAppIdentifier: string, appleIdUsername?: string | null } | null, error?: { __typename?: 'SubmissionError', errorCode?: string | null, message?: string | null } | null }>, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null, applicationArchiveUrl?: string | null, buildArtifactsUrl?: string | null } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'SSOUser', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string }, metrics?: { __typename?: 'BuildMetrics', buildWaitTime?: number | null, buildQueueTime?: number | null, buildDuration?: number | null } | null };
export type BuildWithFingerprintFragment = { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, gitCommitMessage?: string | null, initialQueuePosition?: number | null, queuePosition?: number | null, estimatedWaitTimeLeftSeconds?: number | null, priority: BuildPriority, createdAt: any, updatedAt: any, message?: string | null, completedAt?: any | null, expirationDate?: any | null, isForIosSimulator: boolean, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, builds: { __typename?: 'AppBuildsConnection', edges: Array<{ __typename?: 'AppBuildEdge', node: { __typename?: 'Build', platform: AppPlatform, id: string } }> }, updates: { __typename?: 'AppUpdatesConnection', edges: Array<{ __typename?: 'AppUpdateEdge', node: { __typename?: 'Update', id: string, platform: string } }> } } | null, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null, applicationArchiveUrl?: string | null, buildArtifactsUrl?: string | null } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'SSOUser', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string }, metrics?: { __typename?: 'BuildMetrics', buildWaitTime?: number | null, buildQueueTime?: number | null, buildDuration?: number | null } | null };
export type EnvironmentSecretFragment = { __typename?: 'EnvironmentSecret', id: string, name: string, type: EnvironmentSecretType, createdAt: any };
export type EnvironmentVariableFragment = { __typename?: 'EnvironmentVariable', id: string, name: string, value?: string | null, environments?: Array<any> | null, createdAt: any, updatedAt: any, scope: EnvironmentVariableScope, visibility?: EnvironmentVariableVisibility | null, type: EnvironmentSecretType };
export type EnvironmentVariableFragment = { __typename?: 'EnvironmentVariable', id: string, name: string, value?: string | null, environments?: Array<EnvironmentVariableEnvironment> | null, createdAt: any, updatedAt: any, scope: EnvironmentVariableScope, visibility?: EnvironmentVariableVisibility | null, type: EnvironmentSecretType };
export type EnvironmentVariableWithSecretFragment = { __typename?: 'EnvironmentVariableWithSecret', id: string, name: string, value?: string | null, environments?: Array<any> | null, createdAt: any, updatedAt: any, scope: EnvironmentVariableScope, visibility: EnvironmentVariableVisibility, type: EnvironmentSecretType };
export type EnvironmentVariableWithSecretFragment = { __typename?: 'EnvironmentVariableWithSecret', id: string, name: string, value?: string | null, environments?: Array<EnvironmentVariableEnvironment> | null, createdAt: any, updatedAt: any, scope: EnvironmentVariableScope, visibility: EnvironmentVariableVisibility, type: EnvironmentSecretType };
export type FingerprintFragment = { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, builds: { __typename?: 'AppBuildsConnection', edges: Array<{ __typename?: 'AppBuildEdge', node: { __typename?: 'Build', platform: AppPlatform, id: string } }> }, updates: { __typename?: 'AppUpdatesConnection', edges: Array<{ __typename?: 'AppUpdateEdge', node: { __typename?: 'Update', id: string, platform: string } }> } };
@@ -10280,11 +10236,11 @@ export type RuntimeFragment = { __typename?: 'Runtime', id: string, version: str
export type StatuspageServiceFragment = { __typename?: 'StatuspageService', id: string, name: StatuspageServiceName, status: StatuspageServiceStatus, incidents: Array<{ __typename?: 'StatuspageIncident', id: string, status: StatuspageIncidentStatus, name: string, impact: StatuspageIncidentImpact, shortlink: string }> };
export type SubmissionFragment = { __typename?: 'Submission', id: string, status: SubmissionStatus, platform: AppPlatform, logFiles: Array<string>, app: { __typename?: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } }, androidConfig?: { __typename?: 'AndroidSubmissionConfig', applicationIdentifier?: string | null, track: string, releaseStatus?: SubmissionAndroidReleaseStatus | null, rollout?: number | null } | null, iosConfig?: { __typename?: 'IosSubmissionConfig', ascAppIdentifier: string, appleIdUsername?: string | null } | null, error?: { __typename?: 'SubmissionError', errorCode?: string | null, message?: string | null } | null };
export type SubmissionFragment = { __typename?: 'Submission', id: string, status: SubmissionStatus, platform: AppPlatform, logFiles: Array<string>, app: { __typename?: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } }, androidConfig?: { __typename?: 'AndroidSubmissionConfig', applicationIdentifier?: string | null, track: SubmissionAndroidTrack, releaseStatus?: SubmissionAndroidReleaseStatus | null, rollout?: number | null } | null, iosConfig?: { __typename?: 'IosSubmissionConfig', ascAppIdentifier: string, appleIdUsername?: string | null } | null, error?: { __typename?: 'SubmissionError', errorCode?: string | null, message?: string | null } | null };
export type UpdateFragment = { __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: any | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string, group: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null };
export type UpdateFragment = { __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: EnvironmentVariableEnvironment | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string, group: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null };
export type UpdateBranchFragment = { __typename?: 'UpdateBranch', id: string, name: string, updates: Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: any | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string, group: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }> };
export type UpdateBranchFragment = { __typename?: 'UpdateBranch', id: string, name: string, updates: Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: EnvironmentVariableEnvironment | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string, group: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }> };
export type UpdateBranchBasicInfoFragment = { __typename?: 'UpdateBranch', id: string, name: string };
@@ -10294,7 +10250,7 @@ export type WebhookFragment = { __typename?: 'Webhook', id: string, event: Webho
export type WorkflowFragment = { __typename?: 'Workflow', id: string, name?: string | null, fileName: string, createdAt: any, updatedAt: any };
export type WorkflowJobFragment = { __typename?: 'WorkflowJob', id: string, key: string, name: string, status: WorkflowJobStatus, type: WorkflowJobType, outputs: any, createdAt: any, updatedAt: any, workflowRun: { __typename?: 'WorkflowRun', id: string }, turtleJobRun?: { __typename?: 'JobRun', id: string, logFileUrls: Array<string>, artifacts: Array<{ __typename?: 'WorkflowArtifact', id: string, name: string, contentType?: string | null, fileSizeBytes?: number | null, filename: string, downloadUrl?: string | null }>, errors: Array<{ __typename?: 'JobRunError', errorCode: string, message: string }> } | null, turtleBuild?: { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, gitCommitMessage?: string | null, initialQueuePosition?: number | null, queuePosition?: number | null, estimatedWaitTimeLeftSeconds?: number | null, priority: BuildPriority, createdAt: any, updatedAt: any, message?: string | null, completedAt?: any | null, expirationDate?: any | null, isForIosSimulator: boolean, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null, applicationArchiveUrl?: string | null, buildArtifactsUrl?: string | null } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'SSOUser', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string }, metrics?: { __typename?: 'BuildMetrics', buildWaitTime?: number | null, buildQueueTime?: number | null, buildDuration?: number | null } | null } | null, errors: Array<{ __typename?: 'WorkflowJobError', title: string, message: string }> };
export type WorkflowJobFragment = { __typename?: 'WorkflowJob', id: string, key: string, name: string, status: WorkflowJobStatus, type: WorkflowJobType, outputs: any, createdAt: any, updatedAt: any, workflowRun: { __typename?: 'WorkflowRun', id: string }, turtleJobRun?: { __typename?: 'JobRun', id: string, logFileUrls: Array<string>, errors: Array<{ __typename?: 'JobRunError', errorCode: string, message: string }> } | null, errors: Array<{ __typename?: 'WorkflowJobError', title: string, message: string }> };
export type WorkflowRunFragment = { __typename?: 'WorkflowRun', id: string, status: WorkflowRunStatus, gitCommitMessage?: string | null, gitCommitHash?: string | null, requestedGitRef?: string | null, triggeringLabelName?: string | null, triggerEventType: WorkflowRunTriggerEventType, triggeringSchedule?: string | null, createdAt: any, updatedAt: any, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, errors: Array<{ __typename?: 'WorkflowRunError', title?: string | null, message: string }>, workflow: { __typename?: 'Workflow', id: string, name?: string | null, fileName: string } };
@@ -7,19 +7,37 @@ import {
CreateBulkEnvironmentVariablesForAppMutation,
CreateEnvironmentVariableForAccountMutation,
CreateEnvironmentVariableForAppMutation,
CreateEnvironmentVariableInput,
CreateSharedEnvironmentVariableInput,
DeleteEnvironmentVariableMutation,
EnvironmentSecretType,
EnvironmentVariableEnvironment,
EnvironmentVariableFragment,
UpdateEnvironmentVariableInput,
EnvironmentVariableVisibility,
UpdateEnvironmentVariableMutation,
} from '../generated';
import { EnvironmentVariableFragmentNode } from '../types/EnvironmentVariable';
type CreateVariableArgs = {
value: string;
name: string;
visibility: EnvironmentVariableVisibility;
environments: EnvironmentVariableEnvironment[];
type: EnvironmentSecretType;
isGlobal?: boolean;
fileName?: string;
};
export type EnvironmentVariablePushInput = {
name: string;
value: string;
environments: EnvironmentVariableEnvironment[];
visibility: EnvironmentVariableVisibility;
overwrite?: boolean;
};
export const EnvironmentVariableMutation = {
async createSharedVariableAsync(
graphqlClient: ExpoGraphqlClient,
input: CreateSharedEnvironmentVariableInput,
input: CreateVariableArgs,
accountId: string
): Promise<EnvironmentVariableFragment> {
const data = await withErrorHandlingAsync(
@@ -51,7 +69,7 @@ export const EnvironmentVariableMutation = {
},
async createForAppAsync(
graphqlClient: ExpoGraphqlClient,
input: CreateEnvironmentVariableInput,
input: CreateVariableArgs,
appId: string
): Promise<EnvironmentVariableFragment> {
const data = await withErrorHandlingAsync(
@@ -80,7 +98,7 @@ export const EnvironmentVariableMutation = {
},
async updateAsync(
graphqlClient: ExpoGraphqlClient,
input: UpdateEnvironmentVariableInput
input: Partial<CreateVariableArgs> & { id: string }
): Promise<EnvironmentVariableFragment> {
const data = await withErrorHandlingAsync(
graphqlClient
@@ -125,7 +143,7 @@ export const EnvironmentVariableMutation = {
},
async createBulkEnvironmentVariablesForAppAsync(
graphqlClient: ExpoGraphqlClient,
input: CreateEnvironmentVariableInput[],
input: EnvironmentVariablePushInput[],
appId: string
): Promise<boolean> {
await withErrorHandlingAsync(
@@ -1,20 +1,17 @@
import { FingerprintSource } from '@expo/eas-build-job';
import { print } from 'graphql';
import gql from 'graphql-tag';
import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
import { withErrorHandlingAsync } from '../client';
import {
CreateFingeprintMutation,
FingerprintFragment,
FingerprintSourceInput,
} from '../generated';
import { CreateFingeprintMutation, FingerprintFragment } from '../generated';
import { FingerprintFragmentNode } from '../types/Fingerprint';
export const FingerprintMutation = {
async createFingerprintAsync(
graphqlClient: ExpoGraphqlClient,
appId: string,
fingerprintData: { hash: string; source?: FingerprintSourceInput }
fingerprintData: { hash: string; source?: FingerprintSource }
): Promise<FingerprintFragment> {
const data = await withErrorHandlingAsync(
graphqlClient
@@ -1,10 +1,10 @@
import { print } from 'graphql';
import gql from 'graphql-tag';
import { EnvironmentVariableEnvironment } from '../../build/utils/environment';
import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
import { withErrorHandlingAsync } from '../client';
import {
EnvironmentVariableEnvironment,
EnvironmentVariableFragment,
EnvironmentVariablesByAppIdQuery,
EnvironmentVariablesSharedQuery,
@@ -20,10 +20,6 @@ export const BuildFragmentNode = gql`
applicationArchiveUrl
buildArtifactsUrl
}
fingerprint {
id
hash
}
initiatingActor {
__typename
id
@@ -1,7 +1,5 @@
import gql from 'graphql-tag';
import { BuildFragmentNode } from './Build';
export const WorkflowJobFragmentNode = gql`
fragment WorkflowJobFragment on WorkflowJob {
id
@@ -15,23 +13,11 @@ export const WorkflowJobFragmentNode = gql`
turtleJobRun {
id
logFileUrls
artifacts {
id
name
contentType
fileSizeBytes
filename
downloadUrl
}
errors {
errorCode
message
}
}
turtleBuild {
id
...BuildFragment
}
outputs
errors {
title
@@ -40,5 +26,4 @@ export const WorkflowJobFragmentNode = gql`
createdAt
updatedAt
}
${BuildFragmentNode}
`;
-6
View File
@@ -6,9 +6,6 @@ import terminalLink from 'terminal-link';
type Color = (...text: string[]) => string;
// eslint-disable-next-line import/no-extraneous-dependencies
const nodeDebug = require('debug')('eas:log:debug') as (...args: any[]) => void;
export default class Log {
public static readonly isDebug = boolish('EXPO_DEBUG', false);
@@ -37,9 +34,6 @@ export default class Log {
public static debug(...args: any[]): void {
if (Log.isDebug) {
Log.consoleLog(...args);
} else {
Log.updateIsLastLineNewLine(args);
nodeDebug(...args);
}
}
@@ -1,41 +0,0 @@
import { selectAsync } from '../../prompts';
import { PackageManager, promptForPackageManagerAsync } from '../installDependencies';
jest.mock('../../prompts');
describe('installDependencies', () => {
beforeEach(() => {
jest.resetAllMocks();
});
describe('promptForPackageManagerAsync', () => {
it.each(['npm', 'yarn', 'pnpm'])('returns %s when user selects %s', async packageManager => {
jest.mocked(selectAsync).mockResolvedValue(packageManager as PackageManager);
const result = await promptForPackageManagerAsync();
expect(selectAsync).toHaveBeenCalledWith(
'Which package manager would you like to use?',
[
{ title: 'npm', value: 'npm' },
{ title: 'Yarn', value: 'yarn' },
{ title: 'pnpm', value: 'pnpm' },
],
{ initial: 'npm' }
);
expect(result).toBe(packageManager);
});
it('defaults to npm as initial selection', async () => {
jest.mocked(selectAsync).mockResolvedValue('npm');
await promptForPackageManagerAsync();
expect(selectAsync).toHaveBeenCalledWith(
expect.any(String),
expect.any(Array),
expect.objectContaining({ initial: 'npm' })
);
});
});
});
@@ -1,29 +1,13 @@
import { runCommandAsync } from './runCommand';
import { selectAsync } from '../prompts';
export type PackageManager = 'npm' | 'yarn' | 'pnpm';
export async function promptForPackageManagerAsync(): Promise<PackageManager> {
return await selectAsync(
'Which package manager would you like to use?',
[
{ title: 'npm', value: 'npm' },
{ title: 'Yarn', value: 'yarn' },
{ title: 'pnpm', value: 'pnpm' },
],
{ initial: 'npm' }
);
}
export async function installDependenciesAsync({
projectDir,
packageManager = 'npm',
}: {
projectDir: string;
packageManager?: PackageManager;
}): Promise<void> {
// TODO: add support for other package managers
await runCommandAsync({
command: packageManager,
command: 'npm',
args: ['install'],
cwd: projectDir,
shouldShowStderrLine: line => {
@@ -32,7 +16,7 @@ export async function installDependenciesAsync({
!line.includes('deprecated') &&
!line.includes('no longer maintained') &&
!line.includes('has been moved') &&
!(line === packageManager)
!(line === 'npm')
);
},
});
@@ -1,14 +1,11 @@
import { FingerprintSource, FingerprintSourceType } from '@expo/eas-build-job';
import fs from 'fs-extra';
import path from 'path';
import { v4 as uuidv4 } from 'uuid';
import { LocalBuildMode } from '../build/local';
import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
import {
FingerprintSourceInput,
FingerprintSourceType,
UploadSessionType,
} from '../graphql/generated';
import { UploadSessionType } from '../graphql/generated';
import Log from '../log';
import { uploadFileAtPathToGCSAsync } from '../uploads';
import { getTmpDirectory } from '../utils/paths';
@@ -28,15 +25,8 @@ export async function maybeUploadFingerprintAsync({
localBuildMode?: LocalBuildMode;
}): Promise<{
hash: string;
fingerprintSource?: FingerprintSourceInput;
fingerprintSource?: FingerprintSource;
}> {
if (localBuildMode === LocalBuildMode.LOCAL_BUILD_PLUGIN) {
// We're not uploading local build fingerprints to EAS
return {
hash,
};
}
await fs.mkdirp(getTmpDirectory());
const fingerprintLocation = path.join(getTmpDirectory(), `${uuidv4()}-runtime-fingerprint.json`);
@@ -45,6 +35,17 @@ export async function maybeUploadFingerprintAsync({
sources: fingerprint.fingerprintSources,
});
if (localBuildMode === LocalBuildMode.LOCAL_BUILD_PLUGIN) {
return {
hash,
fingerprintSource: {
type: FingerprintSourceType.PATH,
path: fingerprintLocation,
isDebugFingerprint: fingerprint.isDebugFingerprintSource,
},
};
}
let fingerprintGCSBucketKey = undefined;
try {
fingerprintGCSBucketKey = await uploadFileAtPathToGCSAsync(
@@ -70,7 +71,7 @@ export async function maybeUploadFingerprintAsync({
return {
hash,
fingerprintSource: {
type: FingerprintSourceType.Gcs,
type: FingerprintSourceType.GCS,
bucketKey: fingerprintGCSBucketKey,
isDebugFingerprint: fingerprint.isDebugFingerprintSource,
},
+6 -7
View File
@@ -1,6 +1,6 @@
import { ExpoConfig, Platform as ExpoConfigPlatform } from '@expo/config';
import { Updates } from '@expo/config-plugins';
import { Env, Platform, Workflow } from '@expo/eas-build-job';
import { Env, FingerprintSource, Platform, Workflow } from '@expo/eas-build-job';
import JsonFile from '@expo/json-file';
import assert from 'assert';
import chalk from 'chalk';
@@ -25,7 +25,6 @@ import {
AppPlatform,
AssetMetadataStatus,
BuildFragment,
FingerprintSourceInput,
PartialManifestAsset,
UpdateRolloutInfo,
UpdateRolloutInfoGroup,
@@ -750,7 +749,7 @@ type FingerprintInfoGroup = {
type FingerprintInfo = {
fingerprintHash: string;
fingerprintSource: FingerprintSourceInput;
fingerprintSource: FingerprintSource;
};
export async function getRuntimeVersionInfoObjectsAsync({
@@ -905,14 +904,14 @@ export async function maybeCalculateFingerprintForRuntimeVersionInfoObjectsWitho
graphqlClient: ExpoGraphqlClient;
runtimeToPlatformsAndFingerprintInfoAndFingerprintSourceMapping: (RuntimeVersionInfo & {
platforms: UpdatePublishPlatform[];
expoUpdatesRuntimeFingerprintSource: FingerprintSourceInput | null;
expoUpdatesRuntimeFingerprintSource: FingerprintSource | null;
})[];
workflowsByPlatform: Record<Platform, Workflow>;
env: Env | undefined;
}): Promise<
(RuntimeVersionInfo & {
platforms: UpdatePublishPlatform[];
expoUpdatesRuntimeFingerprintSource: FingerprintSourceInput | null;
expoUpdatesRuntimeFingerprintSource: FingerprintSource | null;
fingerprintInfoGroup: FingerprintInfoGroup;
})[]
> {
@@ -960,7 +959,7 @@ export async function maybeCalculateFingerprintForRuntimeVersionInfoObjectsWitho
for (const platform of runtimeInfo.platforms) {
const runtimeAndPlatform = `${runtimeInfo.runtimeVersion}-${platform}`;
const fingerprint = uploadedFingerprintsByRuntimeAndPlatform.get(runtimeAndPlatform);
if (fingerprint?.uploadedSource) {
if (fingerprint && fingerprint.uploadedSource) {
fingerprintInfoGroup[platform] = {
fingerprintHash: fingerprint.hash,
fingerprintSource: fingerprint.uploadedSource,
@@ -981,7 +980,7 @@ export async function maybeCalculateFingerprintForRuntimeVersionInfoObjectsWitho
infoGroup
): infoGroup is RuntimeVersionInfo & {
platforms: UpdatePublishPlatform[];
expoUpdatesRuntimeFingerprintSource: FingerprintSourceInput;
expoUpdatesRuntimeFingerprintSource: FingerprintSource;
expoUpdatesRuntimeFingerprintHash: string;
} =>
!!infoGroup.expoUpdatesRuntimeFingerprintHash &&
@@ -1,5 +1,10 @@
import { Platform } from '@expo/eas-build-job';
import { AndroidReleaseStatus, EasJsonAccessor, EasJsonUtils } from '@expo/eas-json';
import {
AndroidReleaseStatus,
AndroidReleaseTrack,
EasJsonAccessor,
EasJsonUtils,
} from '@expo/eas-json';
import { MissingProfileError } from '@expo/eas-json/build/errors';
import { refreshContextSubmitProfileAsync } from '../commons';
@@ -59,7 +64,7 @@ describe(refreshContextSubmitProfileAsync, () => {
it('returns updated context if profile exists', async () => {
const submitContext = {
profile: {
track: 'internal',
track: AndroidReleaseTrack.internal,
releaseStatus: AndroidReleaseStatus.draft,
changesNotSentForReview: false,
applicationId: 'appId1',
@@ -74,7 +79,7 @@ describe(refreshContextSubmitProfileAsync, () => {
_profileName: string | undefined
) => {
return {
track: 'beta',
track: AndroidReleaseTrack.beta,
releaseStatus: AndroidReleaseStatus.inProgress,
changesNotSentForReview: true,
applicationId: 'appId2',
@@ -86,7 +91,7 @@ describe(refreshContextSubmitProfileAsync, () => {
expect(result).toEqual({
profile: {
track: 'beta',
track: AndroidReleaseTrack.beta,
releaseStatus: AndroidReleaseStatus.inProgress,
changesNotSentForReview: true,
applicationId: 'appId2',
@@ -96,7 +101,7 @@ describe(refreshContextSubmitProfileAsync, () => {
it('returns unmodified context if profile does not exist', async () => {
const submitContext = {
profile: {
track: 'internal',
track: AndroidReleaseTrack.internal,
releaseStatus: AndroidReleaseStatus.draft,
changesNotSentForReview: false,
applicationId: 'appId1',
@@ -118,7 +123,7 @@ describe(refreshContextSubmitProfileAsync, () => {
expect(result).toEqual({
profile: {
track: 'internal',
track: AndroidReleaseTrack.internal,
releaseStatus: AndroidReleaseStatus.draft,
changesNotSentForReview: false,
applicationId: 'appId1',
@@ -1,10 +1,10 @@
import { Platform } from '@expo/eas-build-job';
import { AndroidReleaseStatus } from '@expo/eas-json';
import { AndroidReleaseStatus, AndroidReleaseTrack } from '@expo/eas-json';
import { Result, result } from '@expo/results';
import AndroidSubmitter, { AndroidSubmissionOptions } from './AndroidSubmitter';
import { ServiceAccountSource, ServiceAccountSourceType } from './ServiceAccountSource';
import { SubmissionAndroidReleaseStatus } from '../../graphql/generated';
import { SubmissionAndroidReleaseStatus, SubmissionAndroidTrack } from '../../graphql/generated';
import Log from '../../log';
import {
AmbiguousApplicationIdError,
@@ -50,12 +50,12 @@ export default class AndroidSubmitCommand {
private async getAndroidSubmissionOptionsAsync(
archiveSource: ArchiveSource
): Promise<AndroidSubmissionOptions> {
const track = this.ctx.profile.track || 'internal';
const track = this.resolveTrack();
const releaseStatus = this.resolveReleaseStatus();
const rollout = this.resolveRollout();
const serviceAccountSource = await this.resolveServiceAccountSourceAsync();
const errored = [releaseStatus, serviceAccountSource, rollout].filter(r => !r.ok);
const errored = [track, releaseStatus, serviceAccountSource, rollout].filter(r => !r.ok);
if (errored.length > 0) {
const message = errored.map(err => err.reason?.message).join('\n');
Log.error(message);
@@ -64,7 +64,7 @@ export default class AndroidSubmitCommand {
return {
projectId: this.ctx.projectId,
track,
track: track.enforceValue(),
releaseStatus: releaseStatus.enforceValue(),
rollout: rollout.enforceValue(),
archiveSource,
@@ -91,6 +91,27 @@ export default class AndroidSubmitCommand {
}
}
private resolveTrack(): Result<SubmissionAndroidTrack> {
const { track } = this.ctx.profile;
if (!track) {
return result(SubmissionAndroidTrack.Internal);
}
const capitalizedTrack = capitalizeFirstLetter(track);
if (capitalizedTrack in SubmissionAndroidTrack) {
return result(
SubmissionAndroidTrack[capitalizedTrack as keyof typeof SubmissionAndroidTrack]
);
} else {
return result(
new Error(
`Unsupported track: ${track} (valid options: ${Object.keys(AndroidReleaseTrack).join(
', '
)})`
)
);
}
}
private resolveReleaseStatus(): Result<SubmissionAndroidReleaseStatus> {
const { releaseStatus } = this.ctx.profile;
if (!releaseStatus) {
@@ -10,6 +10,7 @@ import { SubmissionEvent } from '../../analytics/AnalyticsManager';
import {
AndroidSubmissionConfigInput,
SubmissionAndroidReleaseStatus,
SubmissionAndroidTrack,
SubmissionFragment,
} from '../../graphql/generated';
import { SubmissionMutation } from '../../graphql/mutations/SubmissionMutation';
@@ -141,7 +142,7 @@ type SummaryData = {
projectId: string;
releaseStatus?: SubmissionAndroidReleaseStatus;
rollout?: number;
track: string;
track: SubmissionAndroidTrack;
} & ArchiveSourceSummaryFields;
const SummaryHumanReadableKeys: Record<keyof SummaryData, string> = {
@@ -1,5 +1,5 @@
import { Platform } from '@expo/eas-build-job';
import { AndroidReleaseStatus } from '@expo/eas-json';
import { AndroidReleaseStatus, AndroidReleaseTrack } from '@expo/eas-json';
import { vol } from 'memfs';
import { instance, mock } from 'ts-mockito';
import { v4 as uuidv4 } from 'uuid';
@@ -14,6 +14,7 @@ import {
AppPlatform,
BuildFragment,
SubmissionAndroidReleaseStatus,
SubmissionAndroidTrack,
SubmissionArchiveSourceType,
} from '../../../graphql/generated';
import { SubmissionMutation } from '../../../graphql/mutations/SubmissionMutation';
@@ -117,7 +118,7 @@ describe(AndroidSubmitCommand, () => {
url: 'http://expo.dev/fake.apk',
},
profile: {
track: 'internal',
track: AndroidReleaseTrack.internal,
releaseStatus: AndroidReleaseStatus.draft,
changesNotSentForReview: false,
},
@@ -157,7 +158,7 @@ describe(AndroidSubmitCommand, () => {
},
profile: {
serviceAccountKeyPath: '/google-service-account.json',
track: 'internal',
track: AndroidReleaseTrack.internal,
releaseStatus: AndroidReleaseStatus.draft,
changesNotSentForReview: false,
},
@@ -182,7 +183,7 @@ describe(AndroidSubmitCommand, () => {
config: {
googleServiceAccountKeyJson: fakeFiles['/google-service-account.json'],
releaseStatus: SubmissionAndroidReleaseStatus.Draft,
track: 'internal',
track: SubmissionAndroidTrack.Internal,
changesNotSentForReview: false,
isVerboseFastlaneEnabled: false,
},
@@ -205,7 +206,7 @@ describe(AndroidSubmitCommand, () => {
},
profile: {
serviceAccountKeyPath: '/google-service-account.json',
track: 'internal',
track: AndroidReleaseTrack.internal,
releaseStatus: AndroidReleaseStatus.inProgress,
changesNotSentForReview: false,
},
@@ -230,7 +231,7 @@ describe(AndroidSubmitCommand, () => {
config: {
googleServiceAccountKeyJson: fakeFiles['/google-service-account.json'],
releaseStatus: SubmissionAndroidReleaseStatus.InProgress,
track: 'internal',
track: SubmissionAndroidTrack.Internal,
changesNotSentForReview: false,
isVerboseFastlaneEnabled: false,
},
@@ -256,7 +257,7 @@ describe(AndroidSubmitCommand, () => {
},
profile: {
serviceAccountKeyPath: '/google-service-account.json',
track: 'internal',
track: AndroidReleaseTrack.internal,
releaseStatus: AndroidReleaseStatus.draft,
changesNotSentForReview: false,
},
@@ -279,7 +280,7 @@ describe(AndroidSubmitCommand, () => {
config: {
googleServiceAccountKeyJson: fakeFiles['/google-service-account.json'],
releaseStatus: SubmissionAndroidReleaseStatus.Draft,
track: 'internal',
track: SubmissionAndroidTrack.Internal,
changesNotSentForReview: false,
isVerboseFastlaneEnabled: false,
},
@@ -308,7 +309,7 @@ describe(AndroidSubmitCommand, () => {
.mockImplementation(async (ctx: SubmissionContext<Platform>, _archiveProfile: string) => {
ctx.profile = {
serviceAccountKeyPath: '/google-other-service-account.json',
track: 'beta',
track: AndroidReleaseTrack.beta,
releaseStatus: AndroidReleaseStatus.draft,
changesNotSentForReview: false,
applicationId: 'otherAppId',
@@ -322,7 +323,7 @@ describe(AndroidSubmitCommand, () => {
archiveFlags: {},
profile: {
serviceAccountKeyPath: '/google-service-account.json',
track: 'internal',
track: AndroidReleaseTrack.internal,
releaseStatus: AndroidReleaseStatus.draft,
changesNotSentForReview: false,
},
@@ -349,7 +350,7 @@ describe(AndroidSubmitCommand, () => {
config: {
googleServiceAccountKeyJson: fakeFiles['/google-other-service-account.json'],
releaseStatus: SubmissionAndroidReleaseStatus.Draft,
track: 'beta',
track: SubmissionAndroidTrack.Beta,
changesNotSentForReview: false,
rollout: undefined,
isVerboseFastlaneEnabled: false,
@@ -386,7 +387,7 @@ describe(AndroidSubmitCommand, () => {
archiveFlags: {},
profile: {
serviceAccountKeyPath: '/google-service-account.json',
track: 'internal',
track: AndroidReleaseTrack.internal,
releaseStatus: AndroidReleaseStatus.draft,
changesNotSentForReview: false,
},
@@ -413,7 +414,7 @@ describe(AndroidSubmitCommand, () => {
config: {
googleServiceAccountKeyJson: fakeFiles['/google-service-account.json'],
releaseStatus: SubmissionAndroidReleaseStatus.Draft,
track: 'internal',
track: SubmissionAndroidTrack.Internal,
changesNotSentForReview: false,
rollout: undefined,
isVerboseFastlaneEnabled: false,
@@ -443,7 +444,7 @@ describe(AndroidSubmitCommand, () => {
.mockImplementation(async (ctx: SubmissionContext<Platform>, _archiveProfile: string) => {
ctx.profile = {
serviceAccountKeyPath: '/google-other-service-account.json',
track: 'beta',
track: AndroidReleaseTrack.beta,
releaseStatus: AndroidReleaseStatus.draft,
changesNotSentForReview: false,
applicationId: 'otherAppId',
@@ -457,7 +458,7 @@ describe(AndroidSubmitCommand, () => {
archiveFlags: {},
profile: {
serviceAccountKeyPath: '/google-service-account.json',
track: 'internal',
track: AndroidReleaseTrack.internal,
releaseStatus: AndroidReleaseStatus.draft,
changesNotSentForReview: false,
},
@@ -485,7 +486,7 @@ describe(AndroidSubmitCommand, () => {
config: {
googleServiceAccountKeyJson: fakeFiles['/google-service-account.json'],
releaseStatus: SubmissionAndroidReleaseStatus.Draft,
track: 'internal',
track: SubmissionAndroidTrack.Internal,
changesNotSentForReview: false,
rollout: undefined,
isVerboseFastlaneEnabled: false,
@@ -1,5 +1,5 @@
import { Platform } from '@expo/eas-build-job';
import { AndroidReleaseStatus } from '@expo/eas-json';
import { AndroidReleaseStatus, AndroidReleaseTrack } from '@expo/eas-json';
import { vol } from 'memfs';
import { instance, mock } from 'ts-mockito';
import { v4 as uuidv4 } from 'uuid';
@@ -151,7 +151,7 @@ describe(getServiceAccountKeyResultAsync, () => {
url: 'http://expo.dev/fake.apk',
},
profile: {
track: 'internal',
track: AndroidReleaseTrack.internal,
releaseStatus: AndroidReleaseStatus.draft,
changesNotSentForReview: false,
},
@@ -195,7 +195,7 @@ describe(getServiceAccountKeyResultAsync, () => {
url: 'http://expo.dev/fake.apk',
},
profile: {
track: 'internal',
track: AndroidReleaseTrack.internal,
releaseStatus: AndroidReleaseStatus.draft,
changesNotSentForReview: false,
},
@@ -235,7 +235,7 @@ describe(getServiceAccountKeyResultAsync, () => {
url: 'http://expo.dev/fake.apk',
},
profile: {
track: 'internal',
track: AndroidReleaseTrack.internal,
releaseStatus: AndroidReleaseStatus.draft,
changesNotSentForReview: false,
},
@@ -96,9 +96,6 @@ export async function getSessionUsingBrowserAuthFlowAsync({
);
const port = address.port;
const authorizeUrl = buildExpoSsoLoginUrl(port);
Log.log(
`If your browser doesn't automatically open, visit this link to log in: ${authorizeUrl}`
);
void openBrowserAsync(authorizeUrl);
});
+5 -30
View File
@@ -1,8 +1,10 @@
import chalk from 'chalk';
import { EnvironmentVariableEnvironment } from '../build/utils/environment';
import { EnvironmentSecretType, EnvironmentVariableVisibility } from '../graphql/generated';
import { RequestedPlatform } from '../platform';
import {
EnvironmentSecretType,
EnvironmentVariableEnvironment,
EnvironmentVariableVisibility,
} from '../graphql/generated';
import { promptAsync, selectAsync } from '../prompts';
export async function promptVariableTypeAsync(
@@ -201,30 +203,3 @@ export async function promptVariableNameAsync(
return name;
}
export async function promptPlatformAsync({
message,
}: {
message: string;
}): Promise<RequestedPlatform> {
const { platform } = await promptAsync({
type: 'select',
message,
name: 'platform',
choices: [
{
title: 'All',
value: RequestedPlatform.All,
},
{
title: 'iOS',
value: RequestedPlatform.Ios,
},
{
title: 'Android',
value: RequestedPlatform.Android,
},
],
});
return platform;
}
+1 -1
View File
@@ -1,9 +1,9 @@
import dateFormat from 'dateformat';
import formatFields from './formatFields';
import { EnvironmentVariableEnvironment } from '../build/utils/environment';
import {
EnvironmentSecretType,
EnvironmentVariableEnvironment,
EnvironmentVariableFragment,
EnvironmentVariableScope,
EnvironmentVariableVisibility,
+18 -1
View File
@@ -2,8 +2,9 @@ import { CombinedError } from '@urql/core';
import fs from 'fs';
import path from 'path';
import { getProjectGitHubSettingsUrl } from '../build/utils/url';
import { WorkflowRevisionMutation } from '../graphql/mutations/WorkflowRevisionMutation';
import Log from '../log';
import Log, { link } from '../log';
export namespace WorkflowFile {
export async function readWorkflowFileContentsAsync({
@@ -38,8 +39,12 @@ export namespace WorkflowFile {
export function maybePrintWorkflowFileValidationErrors({
error,
accountName,
projectName,
}: {
error: CombinedError;
accountName: string;
projectName: string;
}): void {
const validationErrors = error.graphQLErrors.flatMap(e => {
return WorkflowRevisionMutation.ValidationErrorExtensionZ.safeParse(e.extensions).data ?? [];
@@ -57,6 +62,18 @@ export namespace WorkflowFile {
}
}
}
const githubNotFoundError = error.graphQLErrors.find(
e => e.extensions.errorCode === 'GITHUB_NOT_FOUND_ERROR'
);
if (githubNotFoundError) {
Log.error(`GitHub repository not found. It is currently required to run workflows.`);
Log.error(
`Please check that the repository exists and that you have access to it. ${link(
getProjectGitHubSettingsUrl(accountName, projectName)
)}`
);
}
}
export function validateYamlExtension(fileName: string): void {
+1 -1
View File
@@ -8,8 +8,8 @@ import path from 'node:path';
import { pipeline } from 'node:stream/promises';
import { pack } from 'tar-stream';
import { EnvironmentVariableEnvironment } from '../build/utils/environment';
import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
import { EnvironmentVariableEnvironment } from '../graphql/generated';
import { EnvironmentVariablesQuery } from '../graphql/queries/EnvironmentVariablesQuery';
/** Returns whether a file or folder is ignored */
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "@expo/eas-json",
"description": "A library for interacting with eas.json",
"version": "16.20.1",
"version": "16.13.2",
"author": "Expo <[email protected]>",
"bugs": "https://github.com/expo/eas-cli/issues",
"dependencies": {
"@babel/code-frame": "7.23.5",
"@expo/eas-build-job": "1.0.231",
"@expo/eas-build-job": "1.0.173",
"chalk": "4.1.2",
"env-string": "1.0.1",
"fs-extra": "11.2.0",
+1 -2
View File
@@ -512,8 +512,7 @@
"markdownDescription": "Path to the JSON file with service account key used to authenticate with Google Play. [Learn more](https://expo.fyi/creating-google-service-account)"
},
"track": {
"type": "string",
"examples": ["beta", "alpha", "internal", "production"],
"enum": ["beta", "alpha", "internal", "production"],
"description": "The track of the application to use. Learn more: https://support.google.com/googleplay/android-developer/answer/9859348?hl=en",
"markdownDescription": "The [track of the application](https://support.google.com/googleplay/android-developer/answer/9859348?hl=en) to use.",
"markdownEnumDescriptions": [
@@ -610,9 +610,7 @@ test('valid eas.json with missing profile', async () => {
const accessor = EasJsonAccessor.fromProjectPath('/project');
const promise = EasJsonUtils.getBuildProfileAsync(accessor, Platform.ANDROID, 'debug');
await expect(promise).rejects.toThrowError(
'Missing build profile in eas.json: "debug". Available profiles: ["production"]'
);
await expect(promise).rejects.toThrowError('Missing build profile in eas.json: debug');
});
test('invalid eas.json when using wrong buildType', async () => {
@@ -635,9 +633,7 @@ test('empty json', async () => {
const accessor = EasJsonAccessor.fromProjectPath('/project');
const promise = EasJsonUtils.getBuildProfileAsync(accessor, Platform.ANDROID, 'production');
await expect(promise).rejects.toThrowError(
'Missing build profile in eas.json: "production". Available profiles: []'
);
await expect(promise).rejects.toThrowError('Missing build profile in eas.json: production');
});
test('invalid semver value', async () => {
+2 -8
View File
@@ -46,16 +46,10 @@ function resolveProfile({
const profile = easJson.build?.[profileName];
if (!profile) {
if (depth === 0) {
throw new MissingProfileError(
`Missing build profile in eas.json: "${profileName}". Available profiles: [${Object.keys(
easJson.build ?? {}
)
.map(profile => `"${profile}"`)
.join(', ')}]`
);
throw new MissingProfileError(`Missing build profile in eas.json: ${profileName}`);
} else {
throw new MissingParentProfileError(
`Extending non-existent build profile in eas.json: "${profileName}"`
`Extending non-existent build profile in eas.json: ${profileName}`
);
}
}
+1 -1
View File
@@ -1,4 +1,4 @@
export { AndroidReleaseStatus, SubmitProfile } from './submit/types';
export { AndroidReleaseStatus, AndroidReleaseTrack, SubmitProfile } from './submit/types';
export { getDefaultProfile as getDefaultSubmitProfile } from './submit/resolver';
export { EasJson, ProfileType, AppVersionSource } from './types';
export { Platform } from '@expo/eas-build-job';
+4 -2
View File
@@ -1,10 +1,12 @@
import Joi from 'joi';
import { AndroidReleaseStatus } from './types';
import { AndroidReleaseStatus, AndroidReleaseTrack } from './types';
export const AndroidSubmitProfileSchema = Joi.object({
serviceAccountKeyPath: Joi.string(),
track: Joi.string().default('internal'),
track: Joi.string()
.valid(...Object.values(AndroidReleaseTrack))
.default(AndroidReleaseTrack.internal),
releaseStatus: Joi.string()
.valid(...Object.values(AndroidReleaseStatus))
.default(AndroidReleaseStatus.completed),
+8 -1
View File
@@ -7,9 +7,16 @@ export enum AndroidReleaseStatus {
inProgress = 'inProgress',
}
export enum AndroidReleaseTrack {
production = 'production',
beta = 'beta',
alpha = 'alpha',
internal = 'internal',
}
export interface AndroidSubmitProfile {
serviceAccountKeyPath?: string;
track: string;
track: AndroidReleaseTrack;
releaseStatus: AndroidReleaseStatus;
changesNotSentForReview: boolean;
applicationId?: string;
+1 -10
View File
@@ -2,9 +2,6 @@
set -eo pipefail
GITHUB_USER=`git config get --global user.name`
GITHUB_EMAIL=`git config get --global user.email`
SCRIPTS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )"/.. && pwd )"
ROOT_DIR="$( cd "$SCRIPTS_DIR"/.. && pwd )"
@@ -13,10 +10,4 @@ $SCRIPTS_DIR/bin/run update-local-plugin
next_version_bump=$($SCRIPTS_DIR/bin/run next-version)
next_version=${1:-$next_version_bump}
if [[ "$GITHUB_USER" == "Expo CI" && "$GITHUB_EMAIL" == "[email protected]" && "$INPUT_DRY_RUN" != "true" ]]; then
echo "Releasing with version $next_version"
lerna version --yes --exact "$next_version"
else
echo "We are running with a normal GitHub user, or the dry run flag is enabled, so run the script in dry run mode, without committing or pushing any changes."
lerna version --yes --exact "$next_version" --no-push --no-git-tag-version
fi
lerna version --exact "$next_version"
Generated
+21 -21
View File
@@ -1539,15 +1539,15 @@
slugify "^1.3.4"
sucrase "3.35.0"
"@expo/[email protected].231":
version "1.0.231"
resolved "https://registry.yarnpkg.com/@expo/eas-build-job/-/eas-build-job-1.0.231.tgz#5c96045276da1e521794523204e9da6051e4dda1"
integrity sha512-jktsZ7IJYcC9lbgUWftbFCpfrhcGwJX4q0qSubUrqvFTMuUyLjCzJqyIZ4znbXLXfJSUPDJNAd4H0wBqKJA9kA==
"@expo/[email protected].173":
version "1.0.173"
resolved "https://registry.yarnpkg.com/@expo/eas-build-job/-/eas-build-job-1.0.173.tgz#e19e0563743cc947fb5419fbeb063f03aed2a796"
integrity sha512-OtayVwXQaQEjJkpeKYvB4N6lsXVX+QSEz5okNx/d+8esI2KCjxOy/hzaqKBTovkxRlmWgE3XLw8RhrjAaBY2Gw==
dependencies:
"@expo/logger" "1.0.221"
"@expo/logger" "1.0.117"
joi "^17.13.1"
semver "^7.6.2"
zod "^4.1.3"
zod "^3.23.8"
"@expo/env@^1.0.0":
version "1.0.0"
@@ -1602,10 +1602,10 @@
"@babel/code-frame" "~7.10.4"
json5 "^2.2.3"
"@expo/[email protected].221":
version "1.0.221"
resolved "https://registry.yarnpkg.com/@expo/logger/-/logger-1.0.221.tgz#bd6ef6e03b3c4bf0872843d8b2a83556892178c0"
integrity sha512-arNkhzq4Ludz9J7PIYWTVYXuT1bO/A8prR8HYAviKuF6fEZfitemNVriGSetQASOE8Vnv3lmBZv6YIwLiFuv/Q==
"@expo/[email protected].117":
version "1.0.117"
resolved "https://registry.yarnpkg.com/@expo/logger/-/logger-1.0.117.tgz#31e302656f33dd015fdde89ad803d710a0e5b8a2"
integrity sha512-tuCT5fmjRjED6HYAf4HgE+UbiHT3JYrkUzUv9FC769goxo4LuuewBNQiDUkeecQTha7aTS5aO2YHlfdipI8gzg==
dependencies:
"@types/bunyan" "^1.8.11"
bunyan "^1.8.15"
@@ -1736,13 +1736,13 @@
dependencies:
cross-spawn "^7.0.3"
"@expo/[email protected].231":
version "1.0.231"
resolved "https://registry.yarnpkg.com/@expo/steps/-/steps-1.0.231.tgz#28fece40d97abb4ccddfad2ea003fa98d414f08a"
integrity sha512-o7Wj6W32S4H4geWC0b3RL5finHmiPT+e8SMP4/4Il2R0oc9er8jLXaj1tQ3fTZvpnlqoMWcFn5fAvaGnxfYDPA==
"@expo/[email protected].173":
version "1.0.173"
resolved "https://registry.yarnpkg.com/@expo/steps/-/steps-1.0.173.tgz#157bf104d3137012bf82b106d5bd0227fd6f67f1"
integrity sha512-XT8+FsZWIzwK+/TGnPrHe0HMQrzRGjTsjVDx8Yt922tL5TkX69XeB/twA0PcPWBLMxq+JiKtFm68yPTPqjIMNg==
dependencies:
"@expo/eas-build-job" "1.0.231"
"@expo/logger" "1.0.221"
"@expo/eas-build-job" "1.0.173"
"@expo/logger" "1.0.117"
"@expo/spawn-async" "^1.7.2"
arg "^5.0.2"
fs-extra "^11.2.0"
@@ -7703,7 +7703,7 @@ foreground-child@^3.1.0:
cross-spawn "^7.0.0"
signal-exit "^4.0.1"
form-data@^4.0.0, form-data@^4.0.4:
[email protected], form-data@^4.0.0, form-data@^4.0.4:
version "4.0.4"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.4.tgz#784cdcce0669a9d68e94d11ac4eea98088edd2c4"
integrity sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==
@@ -15630,7 +15630,7 @@ yocto-queue@^0.1.0:
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
zod@^4.1.3:
version "4.1.8"
resolved "https://registry.yarnpkg.com/zod/-/zod-4.1.8.tgz#54f024adc634dd185006a8415da2bdd495b9d92b"
integrity sha512-5R1P+WwQqmmMIEACyzSvo4JXHY5WiAFHRMg+zBZKgKS+Q1viRa0C1hmUKtHltoIFKtIdki3pRxkmpP74jnNYHQ==
zod@^3.23.8:
version "3.23.8"
resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d"
integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==