mirror of
https://github.com/expo/eas-cli.git
synced 2026-11-13 20:28:08 -10:00
Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
377c7a9ebb | ||
|
|
ef3edcc787 | ||
|
|
e9064b7d25 | ||
|
|
10ab6724e1 | ||
|
|
ab8115b6d3 | ||
|
|
ccc8d5ac02 | ||
|
|
4c07b89eb6 | ||
|
|
189d163a41 | ||
|
|
098b1665bc |
No files matched your search
+18
-2
@@ -6,14 +6,30 @@ This is the log of notable changes to EAS CLI and related packages.
|
||||
|
||||
### 🛠 Breaking changes
|
||||
|
||||
### 🎉 New features
|
||||
|
||||
- Add `build:delete` command. ([#2178](https://github.com/expo/eas-cli/pull/2178) by [@radoslawkrzemien](https://github.com/radoslawkrzemien))
|
||||
- Add filter flags for `platform` and `profile` to `build:cancel` and `build:delete` commands. ([#2178](https://github.com/expo/eas-cli/pull/2178) by [@radoslawkrzemien](https://github.com/radoslawkrzemien))
|
||||
|
||||
### 🐛 Bug fixes
|
||||
|
||||
### 🧹 Chores
|
||||
|
||||
- Remove "bare"-specific **eas.json** template. ([#2179](https://github.com/expo/eas-cli/pull/2179) by [@sjchmiela](https://github.com/sjchmiela))
|
||||
- Prompt users if they want to continue if EAS CLI fails to provision the devices. ([#2181](https://github.com/expo/eas-cli/pull/2181) by [@szdziedzic](https://github.com/szdziedzic))
|
||||
- Update `eas-cli` and `@expo/eas-json` dependencies. ([#2176](https://github.com/expo/eas-cli/pull/2176) by [@szdziedzic](https://github.com/szdziedzic))
|
||||
- Prompt user to map channel on update if unmapped. ([#2185](https://github.com/expo/eas-cli/pull/2185) by [@quinlanj](https://github.com/quinlanj))
|
||||
|
||||
## [6.0.0](https://github.com/expo/eas-cli/releases/tag/v6.0.0) - 2024-01-12
|
||||
|
||||
### 🛠 Breaking changes
|
||||
|
||||
- Drop support for Node 14. ([#2175](https://github.com/expo/eas-cli/pull/2175) by [@szdziedzic](https://github.com/szdziedzic))
|
||||
|
||||
### 🎉 New features
|
||||
|
||||
- Allow undefined update message for EAS Update publishing when no VCS. ([#2148](https://github.com/expo/eas-cli/pull/2148) by [@wschurman](https://github.com/wschurman))
|
||||
|
||||
### 🐛 Bug fixes
|
||||
|
||||
### 🧹 Chores
|
||||
|
||||
- Upgrade `@expo/eas-build-job` to `1.0.56`, thus removing unused (since [#1524](https://github.com/expo/eas-cli/pull/1524)) support for S3 project archives. ([#2165](https://github.com/expo/eas-cli/pull/2165) by [@sjchmiela](https://github.com/sjchmiela))
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
module.exports = {
|
||||
projects: [
|
||||
require('./packages/eas-cli/jest.config.js'),
|
||||
require('./packages/eas-json/jest.config.js'),
|
||||
],
|
||||
testPathIgnorePatterns: ['.*'],
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
import type { Config } from 'jest';
|
||||
|
||||
// eslint-disable-next-line import/no-relative-packages
|
||||
import easCliConfig from './packages/eas-cli/jest.config';
|
||||
// eslint-disable-next-line import/no-relative-packages
|
||||
import easJsonConfig from './packages/eas-json/jest.config';
|
||||
|
||||
const config: Config = {
|
||||
projects: [easCliConfig, easJsonConfig],
|
||||
testPathIgnorePatterns: ['.*'],
|
||||
watchPlugins: ['jest-watch-typeahead/filename', 'jest-watch-typeahead/testname'],
|
||||
collectCoverageFrom: ['<rootDir>/src/**/*.{ts,tsx,js,jsx}'],
|
||||
};
|
||||
|
||||
export default config;
|
||||
@@ -1,7 +0,0 @@
|
||||
module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
testRegex: '/__tests__/.*(test|spec)\\.[jt]sx?$',
|
||||
watchPlugins: ['jest-watch-typeahead/filename', 'jest-watch-typeahead/testname'],
|
||||
collectCoverageFrom: ['<rootDir>/src/**/*.{ts,tsx,js,jsx}'],
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
import type { Config } from 'jest';
|
||||
|
||||
const config: Config = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
testRegex: '/__tests__/.*(test|spec)\\.[jt]sx?$',
|
||||
};
|
||||
|
||||
export default config;
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"npmClient": "yarn",
|
||||
"useWorkspaces": true,
|
||||
"version": "6.0.0",
|
||||
"$schema": "node_modules/lerna/schemas/lerna-schema.json"
|
||||
}
|
||||
+10
-10
@@ -20,19 +20,19 @@
|
||||
"clean": "lerna run clean && rm -rf node_modules coverage"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "29.2.5",
|
||||
"@types/jest": "29.5.11",
|
||||
"@types/node": "20.11.0",
|
||||
"eslint": "8.31.0",
|
||||
"eslint-config-universe": "11.1.1",
|
||||
"eslint-plugin-async-protect": "3.0.0",
|
||||
"eslint": "8.56.0",
|
||||
"eslint-config-universe": "12.0.0",
|
||||
"eslint-plugin-async-protect": "3.1.0",
|
||||
"eslint-plugin-node": "11.1.0",
|
||||
"jest": "29.3.1",
|
||||
"jest-watch-typeahead": "2.2.1",
|
||||
"lerna": "6.4.1",
|
||||
"jest": "29.7.0",
|
||||
"jest-watch-typeahead": "2.2.2",
|
||||
"lerna": "7.4.2",
|
||||
"oclif": "^3.9.0",
|
||||
"prettier": "2.8.2",
|
||||
"ts-jest": "29.0.3",
|
||||
"typescript": "4.9.4"
|
||||
"prettier": "3.1.1",
|
||||
"ts-jest": "29.1.1",
|
||||
"typescript": "5.3.3"
|
||||
},
|
||||
"volta": {
|
||||
"node": "20.11.0",
|
||||
|
||||
Generated
+118
-16
@@ -1213,6 +1213,22 @@
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "isDisabled",
|
||||
"description": null,
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "Boolean",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "isSSOEnabled",
|
||||
"description": "Whether this account has SSO enabled. Can be queried by all members.",
|
||||
@@ -1717,6 +1733,18 @@
|
||||
"description": null,
|
||||
"fields": null,
|
||||
"inputFields": [
|
||||
{
|
||||
"name": "searchTerm",
|
||||
"description": null,
|
||||
"type": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
},
|
||||
"defaultValue": null,
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "sortByField",
|
||||
"description": null,
|
||||
@@ -3117,6 +3145,33 @@
|
||||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "OBJECT",
|
||||
"name": "AccountUsageEASJobsMetadata",
|
||||
"description": null,
|
||||
"fields": [
|
||||
{
|
||||
"name": "resourceClassDisplayName",
|
||||
"description": null,
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
}
|
||||
],
|
||||
"inputFields": null,
|
||||
"interfaces": [],
|
||||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "UNION",
|
||||
"name": "AccountUsageMetadata",
|
||||
@@ -3130,6 +3185,11 @@
|
||||
"kind": "OBJECT",
|
||||
"name": "AccountUsageEASBuildMetadata",
|
||||
"ofType": null
|
||||
},
|
||||
{
|
||||
"kind": "OBJECT",
|
||||
"name": "AccountUsageEASJobsMetadata",
|
||||
"ofType": null
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -14944,6 +15004,18 @@
|
||||
"name": "BuildAnnotation",
|
||||
"description": null,
|
||||
"fields": [
|
||||
{
|
||||
"name": "authorUsername",
|
||||
"description": null,
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "buildPhase",
|
||||
"description": null,
|
||||
@@ -15016,6 +15088,18 @@
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "regexFlags",
|
||||
"description": null,
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "regexString",
|
||||
"description": null,
|
||||
@@ -15116,6 +15200,18 @@
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "regexFlags",
|
||||
"description": null,
|
||||
"type": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
},
|
||||
"defaultValue": null,
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "regexString",
|
||||
"description": null,
|
||||
@@ -16546,18 +16642,6 @@
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "buildMode",
|
||||
"description": null,
|
||||
"type": {
|
||||
"kind": "ENUM",
|
||||
"name": "BuildMode",
|
||||
"ofType": null
|
||||
},
|
||||
"defaultValue": null,
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "buildProfile",
|
||||
"description": null,
|
||||
@@ -21091,6 +21175,12 @@
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "JOBS",
|
||||
"description": null,
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "UPDATES",
|
||||
"description": null,
|
||||
@@ -21132,6 +21222,12 @@
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "RUN_TIME",
|
||||
"description": null,
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "UNIQUE_UPDATERS",
|
||||
"description": null,
|
||||
@@ -37385,14 +37481,14 @@
|
||||
{
|
||||
"name": "EAS_BUILD_PROJECT_SOURCES",
|
||||
"description": null,
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
"isDeprecated": true,
|
||||
"deprecationReason": "Use EAS_BUILD_GCS_PROJECT_SOURCES instead."
|
||||
},
|
||||
{
|
||||
"name": "EAS_SUBMIT_APP_ARCHIVE",
|
||||
"description": null,
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
"isDeprecated": true,
|
||||
"deprecationReason": "Use EAS_SUBMIT_GCS_APP_ARCHIVE instead."
|
||||
},
|
||||
{
|
||||
"name": "EAS_SUBMIT_GCS_APP_ARCHIVE",
|
||||
@@ -37530,6 +37626,12 @@
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "MINUTE",
|
||||
"description": null,
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "REQUEST",
|
||||
"description": null,
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
module.exports = {
|
||||
...require('../../jest/jest.config.js'),
|
||||
rootDir: __dirname,
|
||||
roots: ['src', '__mocks__'],
|
||||
globalSetup: './jest/global-setup.ts',
|
||||
setupFilesAfterEnv: ['./jest/setup-after-env.ts'],
|
||||
};
|
||||
@@ -0,0 +1,14 @@
|
||||
import type { Config } from 'jest';
|
||||
|
||||
// eslint-disable-next-line import/no-relative-packages
|
||||
import baseConfig from '../../jest/jest.config';
|
||||
|
||||
const config: Config = {
|
||||
...baseConfig,
|
||||
rootDir: __dirname,
|
||||
roots: ['src', '__mocks__'],
|
||||
globalSetup: './jest/global-setup.ts',
|
||||
setupFilesAfterEnv: ['./jest/setup-after-env.ts'],
|
||||
};
|
||||
|
||||
export default config;
|
||||
@@ -38,26 +38,27 @@
|
||||
"ajv-formats": "2.1.1",
|
||||
"better-opn": "3.0.2",
|
||||
"chalk": "4.1.2",
|
||||
"cli-progress": "3.11.2",
|
||||
"cli-progress": "3.12.0",
|
||||
"dateformat": "4.6.3",
|
||||
"dotenv": "16.0.3",
|
||||
"dotenv": "16.3.1",
|
||||
"env-paths": "2.2.0",
|
||||
"envinfo": "7.8.1",
|
||||
"envinfo": "7.11.0",
|
||||
"fast-deep-equal": "3.1.3",
|
||||
"fast-glob": "3.2.12",
|
||||
"fast-glob": "3.3.2",
|
||||
"figures": "3.2.0",
|
||||
"form-data": "4.0.0",
|
||||
"fs-extra": "10.1.0",
|
||||
"fs-extra": "11.2.0",
|
||||
"getenv": "1.0.0",
|
||||
"gradle-to-js": "2.0.1",
|
||||
"graphql": "16.8.1",
|
||||
"graphql-tag": "2.12.6",
|
||||
"https-proxy-agent": "5.0.1",
|
||||
"ignore": "5.2.4",
|
||||
"ignore": "5.3.0",
|
||||
"indent-string": "4.0.0",
|
||||
"jks-js": "1.1.0",
|
||||
"joi": "17.7.0",
|
||||
"keychain": "1.3.0",
|
||||
"joi": "17.11.0",
|
||||
"jsonwebtoken": "9.0.0",
|
||||
"keychain": "1.5.0",
|
||||
"log-symbols": "4.1.0",
|
||||
"mime": "3.0.0",
|
||||
"minimatch": "5.1.2",
|
||||
@@ -67,55 +68,56 @@
|
||||
"nullthrows": "1.1.1",
|
||||
"ora": "5.1.0",
|
||||
"pkg-dir": "4.2.0",
|
||||
"pngjs": "6.0.0",
|
||||
"pngjs": "7.0.0",
|
||||
"promise-limit": "2.7.0",
|
||||
"promise-retry": "2.0.1",
|
||||
"prompts": "2.4.2",
|
||||
"qrcode-terminal": "0.12.0",
|
||||
"resolve-from": "5.0.0",
|
||||
"semver": "7.5.2",
|
||||
"semver": "7.5.4",
|
||||
"slash": "3.0.0",
|
||||
"tar": "6.1.13",
|
||||
"tar": "6.2.0",
|
||||
"terminal-link": "2.1.1",
|
||||
"tslib": "2.4.1",
|
||||
"turndown": "7.1.1",
|
||||
"tslib": "2.6.2",
|
||||
"turndown": "7.1.2",
|
||||
"untildify": "4.0.0",
|
||||
"uuid": "9.0.0",
|
||||
"uuid": "9.0.1",
|
||||
"wrap-ansi": "7.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@graphql-codegen/cli": "2.16.3",
|
||||
"@graphql-codegen/introspection": "2.2.3",
|
||||
"@graphql-codegen/typescript": "2.8.7",
|
||||
"@graphql-codegen/typescript-operations": "2.5.12",
|
||||
"@types/cli-progress": "3.11.0",
|
||||
"@graphql-codegen/cli": "5.0.0",
|
||||
"@graphql-codegen/introspection": "4.0.0",
|
||||
"@graphql-codegen/typescript": "4.0.1",
|
||||
"@graphql-codegen/typescript-operations": "4.0.1",
|
||||
"@types/cli-progress": "3.11.5",
|
||||
"@types/dateformat": "3.0.1",
|
||||
"@types/envinfo": "7.8.1",
|
||||
"@types/envinfo": "7.8.3",
|
||||
"@types/express": "4.17.15",
|
||||
"@types/fs-extra": "9.0.13",
|
||||
"@types/fs-extra": "11.0.4",
|
||||
"@types/getenv": "^1.0.0",
|
||||
"@types/jsonwebtoken": "8.5.1",
|
||||
"@types/mime": "3.0.1",
|
||||
"@types/node-fetch": "2.6.2",
|
||||
"@types/node-forge": "1.3.1",
|
||||
"@types/pngjs": "6.0.1",
|
||||
"@types/pngjs": "6.0.4",
|
||||
"@types/promise-retry": "1.1.3",
|
||||
"@types/prompts": "2.4.2",
|
||||
"@types/semver": "7.3.13",
|
||||
"@types/tar": "6.1.3",
|
||||
"@types/semver": "7.5.6",
|
||||
"@types/tar": "6.1.10",
|
||||
"@types/tough-cookie": "4.0.2",
|
||||
"@types/uuid": "9.0.0",
|
||||
"@types/uuid": "9.0.7",
|
||||
"@types/wrap-ansi": "3.0.0",
|
||||
"axios": "0.27.2",
|
||||
"eslint-plugin-graphql": "4.0.0",
|
||||
"express": "4.18.2",
|
||||
"memfs": "3.4.13",
|
||||
"mockdate": "3.0.5",
|
||||
"nock": "13.2.9",
|
||||
"nock": "13.4.0",
|
||||
"rimraf": "3.0.2",
|
||||
"ts-deepmerge": "4.0.0",
|
||||
"ts-deepmerge": "6.2.0",
|
||||
"ts-mockito": "2.6.1",
|
||||
"ts-node": "10.9.1",
|
||||
"typescript": "4.9.4"
|
||||
"ts-node": "10.9.2",
|
||||
"typescript": "5.3.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.0.0"
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { AppVersionSource, EasJson } from '@expo/eas-json';
|
||||
import chalk from 'chalk';
|
||||
|
||||
import { getMockEasJson, mockCommandContext, mockProjectId, mockTestCommand } from './utils';
|
||||
import BuildVersionGetView from '../../commands/build/version/get';
|
||||
import { AppVersionQuery } from '../../graphql/queries/AppVersionQuery';
|
||||
import Log from '../../log';
|
||||
import { enableJsonOutput, printJsonOnlyOutput } from '../../utils/json';
|
||||
import { getMockEasJson, mockCommandContext, mockProjectId, mockTestCommand } from './utils';
|
||||
|
||||
jest.mock('../../project/applicationIdentifier');
|
||||
jest.mock('fs');
|
||||
|
||||
@@ -2,12 +2,6 @@ import { AppVersionSource, EasJson } from '@expo/eas-json';
|
||||
import fs from 'fs-extra';
|
||||
import path from 'path';
|
||||
|
||||
import BuildVersionSetView from '../../commands/build/version/set';
|
||||
import { AppVersionMutation } from '../../graphql/mutations/AppVersionMutation';
|
||||
import { AppQuery } from '../../graphql/queries/AppQuery';
|
||||
import { AppVersionQuery } from '../../graphql/queries/AppVersionQuery';
|
||||
import Log from '../../log';
|
||||
import * as prompts from '../../prompts';
|
||||
import {
|
||||
getMockAppFragment,
|
||||
getMockEasJson,
|
||||
@@ -15,6 +9,12 @@ import {
|
||||
mockProjectId,
|
||||
mockTestCommand,
|
||||
} from './utils';
|
||||
import BuildVersionSetView from '../../commands/build/version/set';
|
||||
import { AppVersionMutation } from '../../graphql/mutations/AppVersionMutation';
|
||||
import { AppQuery } from '../../graphql/queries/AppQuery';
|
||||
import { AppVersionQuery } from '../../graphql/queries/AppVersionQuery';
|
||||
import Log from '../../log';
|
||||
import * as prompts from '../../prompts';
|
||||
|
||||
jest.mock('../../project/applicationIdentifier');
|
||||
jest.mock('../../graphql/queries/AppVersionQuery');
|
||||
|
||||
@@ -3,6 +3,13 @@ import { AppVersionSource, EasJson } from '@expo/eas-json';
|
||||
import fs from 'fs-extra';
|
||||
import path from 'path';
|
||||
|
||||
import {
|
||||
getMockAppFragment,
|
||||
getMockEasJson,
|
||||
mockCommandContext,
|
||||
mockProjectId,
|
||||
mockTestCommand,
|
||||
} from './utils';
|
||||
import { updateNativeVersionsAsync as updateAndroidNativeVersionsAsync } from '../../build/android/version';
|
||||
import { updateNativeVersionsAsync as updateIosNativeVersionsAsync } from '../../build/ios/version';
|
||||
import BuildVersionSyncView from '../../commands/build/version/sync';
|
||||
@@ -14,13 +21,6 @@ import { getAppBuildGradleAsync } from '../../project/android/gradleUtils';
|
||||
import { resolveTargetsAsync } from '../../project/ios/target';
|
||||
import { resolveWorkflowAsync } from '../../project/workflow';
|
||||
import * as prompts from '../../prompts';
|
||||
import {
|
||||
getMockAppFragment,
|
||||
getMockEasJson,
|
||||
mockCommandContext,
|
||||
mockProjectId,
|
||||
mockTestCommand,
|
||||
} from './utils';
|
||||
|
||||
jest.mock('../../build/android/version');
|
||||
jest.mock('../../build/ios/version');
|
||||
|
||||
@@ -59,7 +59,7 @@ export interface LocalProjectContext {
|
||||
export function mockCommandContext<
|
||||
C extends {
|
||||
[name: string]: any;
|
||||
} = object
|
||||
} = object,
|
||||
>(
|
||||
commandClass: { contextDefinition: ContextInput<C> },
|
||||
overrides: {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import chalk from 'chalk';
|
||||
import gql from 'graphql-tag';
|
||||
|
||||
import { BranchNotFoundError } from './utils';
|
||||
import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
|
||||
import { PaginatedQueryOptions } from '../commandUtils/pagination';
|
||||
import { withErrorHandlingAsync } from '../graphql/client';
|
||||
@@ -19,7 +20,6 @@ import {
|
||||
paginatedQueryWithConfirmPromptAsync,
|
||||
paginatedQueryWithSelectPromptAsync,
|
||||
} from '../utils/queries';
|
||||
import { BranchNotFoundError } from './utils';
|
||||
|
||||
export const BRANCHES_LIMIT = 50;
|
||||
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
import { instance, mock } from 'ts-mockito';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
|
||||
import { selectBuildToDeleteAsync } from '../../commands/build/delete';
|
||||
import {
|
||||
AppPlatform,
|
||||
BuildFragment,
|
||||
BuildPriority,
|
||||
BuildResourceClass,
|
||||
BuildStatus,
|
||||
} from '../../graphql/generated';
|
||||
import { BuildQuery } from '../../graphql/queries/BuildQuery';
|
||||
import { confirmAsync, selectAsync } from '../../prompts';
|
||||
|
||||
jest.mock('../../ora', () => ({
|
||||
ora: jest.fn().mockImplementation(() => ({
|
||||
start: jest.fn().mockImplementation(() => ({
|
||||
stop: jest.fn(),
|
||||
fail: jest.fn(),
|
||||
})),
|
||||
})),
|
||||
}));
|
||||
jest.mock('../../prompts', () => {
|
||||
return {
|
||||
selectAsync: jest.fn(),
|
||||
confirmAsync: jest.fn(),
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('../../graphql/queries/BuildQuery', () => {
|
||||
const actual = jest.requireActual('../../graphql/queries/BuildQuery');
|
||||
return {
|
||||
BuildQuery: {
|
||||
...actual.BuildQuery,
|
||||
viewBuildsOnAppAsync: jest.fn(),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
describe(selectBuildToDeleteAsync.name, () => {
|
||||
const selectedBuildId = uuid();
|
||||
const projectId = uuid();
|
||||
|
||||
beforeEach(() => {
|
||||
jest
|
||||
.mocked(BuildQuery.viewBuildsOnAppAsync)
|
||||
.mockImplementation(async () => [
|
||||
createMockBuildFragment({ projectId, buildId: selectedBuildId }),
|
||||
]);
|
||||
});
|
||||
|
||||
it('does not return build id when confirmation is rejected', async () => {
|
||||
const graphqlClient = instance(mock<ExpoGraphqlClient>());
|
||||
jest.mocked(confirmAsync).mockResolvedValueOnce(false);
|
||||
expect(selectBuildToDeleteAsync(graphqlClient, projectId, 'blah')).resolves.toEqual(null);
|
||||
});
|
||||
|
||||
it('returns build id when confirmation is confirmed', async () => {
|
||||
const graphqlClient = instance(mock<ExpoGraphqlClient>());
|
||||
jest.mocked(selectAsync).mockResolvedValueOnce(selectedBuildId);
|
||||
jest.mocked(confirmAsync).mockResolvedValueOnce(true);
|
||||
expect(selectBuildToDeleteAsync(graphqlClient, projectId, 'blah')).resolves.toEqual(
|
||||
selectedBuildId
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
function createMockBuildFragment({
|
||||
projectId,
|
||||
buildId,
|
||||
}: {
|
||||
projectId: string;
|
||||
buildId?: string;
|
||||
}): BuildFragment {
|
||||
return {
|
||||
createdAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString(),
|
||||
platform: AppPlatform.Android,
|
||||
id: buildId ?? uuid(),
|
||||
priority: BuildPriority.Normal,
|
||||
project: {
|
||||
__typename: 'App',
|
||||
slug: 'test-project',
|
||||
id: projectId,
|
||||
name: 'test-project',
|
||||
ownerAccount: {
|
||||
__typename: 'Account',
|
||||
id: uuid(),
|
||||
name: 'test-account',
|
||||
},
|
||||
},
|
||||
status: BuildStatus.InQueue,
|
||||
resourceClass: BuildResourceClass.AndroidMedium,
|
||||
};
|
||||
}
|
||||
@@ -3,6 +3,10 @@ import { AppVersionSource } from '@expo/eas-json';
|
||||
import chalk from 'chalk';
|
||||
import nullthrows from 'nullthrows';
|
||||
|
||||
import { transformJob } from './graphql';
|
||||
import { prepareJobAsync } from './prepareJob';
|
||||
import { syncProjectConfigurationAsync } from './syncProjectConfiguration';
|
||||
import { resolveRemoteVersionCodeAsync } from './version';
|
||||
import AndroidCredentialsProvider, {
|
||||
AndroidCredentials,
|
||||
} from '../../credentials/android/AndroidCredentialsProvider';
|
||||
@@ -29,10 +33,6 @@ import {
|
||||
checkNodeEnvVariable,
|
||||
validatePNGsForManagedProjectAsync,
|
||||
} from '../validate';
|
||||
import { transformJob } from './graphql';
|
||||
import { prepareJobAsync } from './prepareJob';
|
||||
import { syncProjectConfigurationAsync } from './syncProjectConfiguration';
|
||||
import { resolveRemoteVersionCodeAsync } from './version';
|
||||
|
||||
export async function createAndroidContextAsync(
|
||||
ctx: CommonContext<Platform.ANDROID>
|
||||
|
||||
@@ -6,13 +6,13 @@ import chalk from 'chalk';
|
||||
import fs from 'fs-extra';
|
||||
import path from 'path';
|
||||
|
||||
import { BumpStrategy, bumpVersionAsync, bumpVersionInAppJsonAsync } from './version';
|
||||
import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
|
||||
import Log from '../../log';
|
||||
import { isExpoUpdatesInstalled } from '../../project/projectUtils';
|
||||
import { resolveWorkflowAsync } from '../../project/workflow';
|
||||
import { syncUpdatesConfigurationAsync } from '../../update/android/UpdatesModule';
|
||||
import { Client } from '../../vcs/vcs';
|
||||
import { BumpStrategy, bumpVersionAsync, bumpVersionInAppJsonAsync } from './version';
|
||||
|
||||
export async function syncProjectConfigurationAsync(
|
||||
graphqlClient: ExpoGraphqlClient,
|
||||
|
||||
@@ -7,6 +7,26 @@ import fs from 'fs-extra';
|
||||
import { GraphQLError } from 'graphql/error';
|
||||
import nullthrows from 'nullthrows';
|
||||
|
||||
import { BuildContext } from './context';
|
||||
import {
|
||||
EasBuildDownForMaintenanceError,
|
||||
EasBuildFreeTierDisabledAndroidError,
|
||||
EasBuildFreeTierDisabledError,
|
||||
EasBuildFreeTierDisabledIOSError,
|
||||
EasBuildFreeTierIosLimitExceededError,
|
||||
EasBuildFreeTierLimitExceededError,
|
||||
EasBuildLegacyResourceClassNotAvailableError,
|
||||
EasBuildProjectArchiveUploadError,
|
||||
EasBuildResourceClassNotAvailableInFreeTierError,
|
||||
EasBuildTooManyPendingBuildsError,
|
||||
RequestValidationError,
|
||||
TurtleDeprecatedJobFormatError,
|
||||
} from './errors';
|
||||
import { transformMetadata } from './graphql';
|
||||
import { LocalBuildMode, runLocalBuildAsync } from './local';
|
||||
import { collectMetadataAsync } from './metadata';
|
||||
import { printDeprecationWarnings } from './utils/printBuildInfo';
|
||||
import { makeProjectTarballAsync, reviewAndCommitChangesAsync } from './utils/repository';
|
||||
import { BuildEvent } from '../analytics/AnalyticsManager';
|
||||
import { withAnalyticsAsync } from '../analytics/common';
|
||||
import { getExpoWebsiteBaseUrl } from '../api';
|
||||
@@ -34,26 +54,6 @@ import { formatBytes } from '../utils/files';
|
||||
import { printJsonOnlyOutput } from '../utils/json';
|
||||
import { createProgressTracker } from '../utils/progress';
|
||||
import { sleepAsync } from '../utils/promise';
|
||||
import { BuildContext } from './context';
|
||||
import {
|
||||
EasBuildDownForMaintenanceError,
|
||||
EasBuildFreeTierDisabledAndroidError,
|
||||
EasBuildFreeTierDisabledError,
|
||||
EasBuildFreeTierDisabledIOSError,
|
||||
EasBuildFreeTierIosLimitExceededError,
|
||||
EasBuildFreeTierLimitExceededError,
|
||||
EasBuildLegacyResourceClassNotAvailableError,
|
||||
EasBuildProjectArchiveUploadError,
|
||||
EasBuildResourceClassNotAvailableInFreeTierError,
|
||||
EasBuildTooManyPendingBuildsError,
|
||||
RequestValidationError,
|
||||
TurtleDeprecatedJobFormatError,
|
||||
} from './errors';
|
||||
import { transformMetadata } from './graphql';
|
||||
import { LocalBuildMode, runLocalBuildAsync } from './local';
|
||||
import { collectMetadataAsync } from './metadata';
|
||||
import { printDeprecationWarnings } from './utils/printBuildInfo';
|
||||
import { makeProjectTarballAsync, reviewAndCommitChangesAsync } from './utils/repository';
|
||||
|
||||
export interface CredentialsResult<Credentials> {
|
||||
source: CredentialsSource.LOCAL | CredentialsSource.REMOTE;
|
||||
@@ -97,7 +97,7 @@ function resolveBuildParamsInput<T extends Platform>(
|
||||
export async function prepareBuildRequestForPlatformAsync<
|
||||
TPlatform extends Platform,
|
||||
Credentials,
|
||||
TJob extends Job
|
||||
TJob extends Job,
|
||||
>(builder: Builder<TPlatform, Credentials, TJob>): Promise<BuildRequestSender> {
|
||||
const { ctx } = builder;
|
||||
const credentialsResult = await withAnalyticsAsync(
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
import { Platform, Workflow } from '@expo/eas-build-job';
|
||||
import { EasJson, EasJsonAccessor } from '@expo/eas-json';
|
||||
import chalk from 'chalk';
|
||||
import fs from 'fs-extra';
|
||||
|
||||
import { maybeBailOnRepoStatusAsync, reviewAndCommitChangesAsync } from './utils/repository';
|
||||
import Log, { learnMore } from '../log';
|
||||
import { resolveWorkflowAsync } from '../project/workflow';
|
||||
import { easCliVersion } from '../utils/easCli';
|
||||
import { Client } from '../vcs/vcs';
|
||||
import { maybeBailOnRepoStatusAsync, reviewAndCommitChangesAsync } from './utils/repository';
|
||||
|
||||
interface ConfigureParams {
|
||||
projectDir: string;
|
||||
@@ -54,7 +52,7 @@ async function configureAsync({
|
||||
}
|
||||
}
|
||||
|
||||
const EAS_JSON_MANAGED_DEFAULT: EasJson = {
|
||||
const EAS_JSON_DEFAULT: EasJson = {
|
||||
cli: {
|
||||
version: `>= ${easCliVersion}`,
|
||||
},
|
||||
@@ -73,43 +71,10 @@ const EAS_JSON_MANAGED_DEFAULT: EasJson = {
|
||||
},
|
||||
};
|
||||
|
||||
const EAS_JSON_BARE_DEFAULT: EasJson = {
|
||||
cli: {
|
||||
version: `>= ${easCliVersion}`,
|
||||
},
|
||||
build: {
|
||||
development: {
|
||||
distribution: 'internal',
|
||||
android: {
|
||||
gradleCommand: ':app:assembleDebug',
|
||||
},
|
||||
ios: {
|
||||
buildConfiguration: 'Debug',
|
||||
},
|
||||
},
|
||||
preview: {
|
||||
distribution: 'internal',
|
||||
},
|
||||
production: {},
|
||||
},
|
||||
submit: {
|
||||
production: {},
|
||||
},
|
||||
};
|
||||
|
||||
async function createEasJsonAsync(projectDir: string, vcsClient: Client): Promise<void> {
|
||||
const easJsonPath = EasJsonAccessor.formatEasJsonPath(projectDir);
|
||||
|
||||
const hasAndroidNativeProject =
|
||||
(await resolveWorkflowAsync(projectDir, Platform.ANDROID, vcsClient)) === Workflow.GENERIC;
|
||||
const hasIosNativeProject =
|
||||
(await resolveWorkflowAsync(projectDir, Platform.IOS, vcsClient)) === Workflow.GENERIC;
|
||||
const easJson =
|
||||
hasAndroidNativeProject || hasIosNativeProject
|
||||
? EAS_JSON_BARE_DEFAULT
|
||||
: EAS_JSON_MANAGED_DEFAULT;
|
||||
|
||||
await fs.writeFile(easJsonPath, `${JSON.stringify(easJson, null, 2)}\n`);
|
||||
await fs.writeFile(easJsonPath, `${JSON.stringify(EAS_JSON_DEFAULT, null, 2)}\n`);
|
||||
await vcsClient.trackFileAsync(easJsonPath);
|
||||
Log.withTick(
|
||||
`Generated ${chalk.bold('eas.json')}. ${learnMore(
|
||||
|
||||
@@ -3,6 +3,7 @@ import { Platform, Workflow } from '@expo/eas-build-job';
|
||||
import { BuildProfile, EasJson } from '@expo/eas-json';
|
||||
import { NodePackageManager } from '@expo/package-manager';
|
||||
|
||||
import { LocalBuildOptions } from './local';
|
||||
import { Analytics, AnalyticsEventProperties } from '../analytics/AnalyticsManager';
|
||||
import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
|
||||
import { CredentialsContext } from '../credentials/context';
|
||||
@@ -13,7 +14,6 @@ import { CustomBuildConfigMetadata } from '../project/customBuildConfig';
|
||||
import { XcodeBuildContext } from '../project/ios/scheme';
|
||||
import { Actor } from '../user/User';
|
||||
import { Client } from '../vcs/vcs';
|
||||
import { LocalBuildOptions } from './local';
|
||||
|
||||
export type CommonContext<T extends Platform> = Omit<BuildContext<T>, 'android' | 'ios'>;
|
||||
|
||||
|
||||
@@ -6,6 +6,11 @@ import getenv from 'getenv';
|
||||
import resolveFrom from 'resolve-from';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
import { createAndroidContextAsync } from './android/build';
|
||||
import { BuildContext, CommonContext } from './context';
|
||||
import { createIosContextAsync } from './ios/build';
|
||||
import { LocalBuildOptions } from './local';
|
||||
import { resolveBuildResourceClassAsync } from './utils/resourceClass';
|
||||
import { Analytics, AnalyticsEventProperties, BuildEvent } from '../analytics/AnalyticsManager';
|
||||
import { DynamicConfigContextFn } from '../commandUtils/context/DynamicProjectConfigContextField';
|
||||
import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
|
||||
@@ -15,11 +20,6 @@ import { getOwnerAccountForProjectIdAsync } from '../project/projectUtils';
|
||||
import { resolveWorkflowAsync } from '../project/workflow';
|
||||
import { Actor } from '../user/User';
|
||||
import { Client } from '../vcs/vcs';
|
||||
import { createAndroidContextAsync } from './android/build';
|
||||
import { BuildContext, CommonContext } from './context';
|
||||
import { createIosContextAsync } from './ios/build';
|
||||
import { LocalBuildOptions } from './local';
|
||||
import { resolveBuildResourceClassAsync } from './utils/resourceClass';
|
||||
|
||||
export async function createBuildContextAsync<T extends Platform>({
|
||||
buildProfileName,
|
||||
|
||||
@@ -62,7 +62,7 @@ describe(evaluateTemplateString, () => {
|
||||
// bare workflow
|
||||
describe(bumpVersionAsync, () => {
|
||||
beforeEach(() => {
|
||||
getPbxproj.mockImplementation(() => ({} as any));
|
||||
getPbxproj.mockImplementation((): any => {});
|
||||
});
|
||||
afterEach(() => {
|
||||
getXCBuildConfigurationFromPbxproj.mockReset();
|
||||
@@ -76,7 +76,7 @@ describe(bumpVersionAsync, () => {
|
||||
buildSettings: {
|
||||
INFOPLIST_FILE: 'myproject/Info.plist',
|
||||
},
|
||||
} as XCBuildConfiguration)
|
||||
}) as XCBuildConfiguration
|
||||
);
|
||||
await bumpVersionAsync({
|
||||
bumpStrategy: BumpStrategy.BUILD_NUMBER,
|
||||
@@ -112,7 +112,7 @@ describe(bumpVersionAsync, () => {
|
||||
buildSettings: {
|
||||
INFOPLIST_FILE: '$(SRCROOT)/myproject/Info2.plist',
|
||||
},
|
||||
} as XCBuildConfiguration)
|
||||
}) as XCBuildConfiguration
|
||||
);
|
||||
await bumpVersionAsync({
|
||||
bumpStrategy: BumpStrategy.BUILD_NUMBER,
|
||||
@@ -147,7 +147,7 @@ describe(bumpVersionAsync, () => {
|
||||
buildSettings: {
|
||||
INFOPLIST_FILE: 'myproject/Info.plist',
|
||||
},
|
||||
} as XCBuildConfiguration)
|
||||
}) as XCBuildConfiguration
|
||||
);
|
||||
await bumpVersionAsync({
|
||||
bumpStrategy: BumpStrategy.APP_VERSION,
|
||||
@@ -182,7 +182,7 @@ describe(bumpVersionAsync, () => {
|
||||
buildSettings: {
|
||||
INFOPLIST_FILE: 'myproject/Info.plist',
|
||||
},
|
||||
} as XCBuildConfiguration)
|
||||
}) as XCBuildConfiguration
|
||||
);
|
||||
await bumpVersionAsync({
|
||||
bumpStrategy: BumpStrategy.NOOP,
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
import { Ios, Job, Metadata, Platform, Workflow } from '@expo/eas-build-job';
|
||||
import { AppVersionSource } from '@expo/eas-json';
|
||||
|
||||
import { ensureIosCredentialsAsync } from './credentials';
|
||||
import { transformJob } from './graphql';
|
||||
import { prepareJobAsync } from './prepareJob';
|
||||
import { syncProjectConfigurationAsync } from './syncProjectConfiguration';
|
||||
import { resolveRemoteBuildNumberAsync } from './version';
|
||||
import { IosCredentials } from '../../credentials/ios/types';
|
||||
import { BuildParamsInput } from '../../graphql/generated';
|
||||
import { BuildMutation, BuildResult } from '../../graphql/mutations/BuildMutation';
|
||||
@@ -15,11 +20,6 @@ import {
|
||||
checkNodeEnvVariable,
|
||||
validatePNGsForManagedProjectAsync,
|
||||
} from '../validate';
|
||||
import { ensureIosCredentialsAsync } from './credentials';
|
||||
import { transformJob } from './graphql';
|
||||
import { prepareJobAsync } from './prepareJob';
|
||||
import { syncProjectConfigurationAsync } from './syncProjectConfiguration';
|
||||
import { resolveRemoteBuildNumberAsync } from './version';
|
||||
|
||||
export async function createIosContextAsync(
|
||||
ctx: CommonContext<Platform.IOS>
|
||||
|
||||
@@ -2,13 +2,13 @@ import { ExpoConfig } from '@expo/config';
|
||||
import { Platform, Workflow } from '@expo/eas-build-job';
|
||||
import { IosVersionAutoIncrement } from '@expo/eas-json';
|
||||
|
||||
import { BumpStrategy, bumpVersionAsync, bumpVersionInAppJsonAsync } from './version';
|
||||
import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
|
||||
import { Target } from '../../credentials/ios/types';
|
||||
import { isExpoUpdatesInstalled } from '../../project/projectUtils';
|
||||
import { resolveWorkflowAsync } from '../../project/workflow';
|
||||
import { syncUpdatesConfigurationAsync } from '../../update/ios/UpdatesModule';
|
||||
import { Client } from '../../vcs/vcs';
|
||||
import { BumpStrategy, bumpVersionAsync, bumpVersionInAppJsonAsync } from './version';
|
||||
|
||||
export async function syncProjectConfigurationAsync(
|
||||
graphqlClient: ExpoGraphqlClient,
|
||||
|
||||
@@ -4,6 +4,10 @@ import { IosEnterpriseProvisioning } from '@expo/eas-json';
|
||||
import fs from 'fs-extra';
|
||||
import resolveFrom from 'resolve-from';
|
||||
|
||||
import { maybeResolveVersionsAsync as maybeResolveAndroidVersionsAsync } from './android/version';
|
||||
import { BuildContext } from './context';
|
||||
import { maybeResolveVersionsAsync as maybeResolveIosVersionsAsync } from './ios/version';
|
||||
import { LocalBuildMode } from './local';
|
||||
import Log from '../log';
|
||||
import { getUsername, isExpoUpdatesInstalled } from '../project/projectUtils';
|
||||
import {
|
||||
@@ -15,10 +19,6 @@ import {
|
||||
readReleaseChannelSafelyAsync as readIosReleaseChannelSafelyAsync,
|
||||
} from '../update/ios/UpdatesModule';
|
||||
import { easCliVersion } from '../utils/easCli';
|
||||
import { maybeResolveVersionsAsync as maybeResolveAndroidVersionsAsync } from './android/version';
|
||||
import { BuildContext } from './context';
|
||||
import { maybeResolveVersionsAsync as maybeResolveIosVersionsAsync } from './ios/version';
|
||||
import { LocalBuildMode } from './local';
|
||||
|
||||
export async function collectMetadataAsync<T extends Platform>(
|
||||
ctx: BuildContext<T>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import chalk from 'chalk';
|
||||
|
||||
import { formatGraphQLBuild } from './utils/formatBuild';
|
||||
import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
|
||||
import { PaginatedQueryOptions } from '../commandUtils/pagination';
|
||||
import { AppPlatform, BuildFilter, BuildFragment } from '../graphql/generated';
|
||||
@@ -11,7 +12,6 @@ import {
|
||||
paginatedQueryWithConfirmPromptAsync,
|
||||
paginatedQueryWithSelectPromptAsync,
|
||||
} from '../utils/queries';
|
||||
import { formatGraphQLBuild } from './utils/formatBuild';
|
||||
|
||||
export const BUILDS_LIMIT = 50;
|
||||
|
||||
|
||||
@@ -13,6 +13,16 @@ import assert from 'assert';
|
||||
import chalk from 'chalk';
|
||||
import nullthrows from 'nullthrows';
|
||||
|
||||
import { prepareAndroidBuildAsync } from './android/build';
|
||||
import { BuildRequestSender, MaybeBuildFragment, waitForBuildEndAsync } from './build';
|
||||
import { ensureProjectConfiguredAsync } from './configure';
|
||||
import { BuildContext } from './context';
|
||||
import { createBuildContextAsync } from './createContext';
|
||||
import { prepareIosBuildAsync } from './ios/build';
|
||||
import { LocalBuildOptions } from './local';
|
||||
import { ensureExpoDevClientInstalledForDevClientBuildsAsync } from './utils/devClient';
|
||||
import { printBuildResults, printLogsUrls } from './utils/printBuildInfo';
|
||||
import { ensureRepoIsCleanAsync } from './utils/repository';
|
||||
import { Analytics } from '../analytics/AnalyticsManager';
|
||||
import { createAndLinkChannelAsync, doesChannelExistAsync } from '../channel/queries';
|
||||
import { DynamicConfigContextFn } from '../commandUtils/context/DynamicProjectConfigContextField';
|
||||
@@ -67,16 +77,6 @@ import { truthy } from '../utils/expodash/filter';
|
||||
import { printJsonOnlyOutput } from '../utils/json';
|
||||
import { ProfileData, getProfilesAsync } from '../utils/profiles';
|
||||
import { Client } from '../vcs/vcs';
|
||||
import { prepareAndroidBuildAsync } from './android/build';
|
||||
import { BuildRequestSender, MaybeBuildFragment, waitForBuildEndAsync } from './build';
|
||||
import { ensureProjectConfiguredAsync } from './configure';
|
||||
import { BuildContext } from './context';
|
||||
import { createBuildContextAsync } from './createContext';
|
||||
import { prepareIosBuildAsync } from './ios/build';
|
||||
import { LocalBuildOptions } from './local';
|
||||
import { ensureExpoDevClientInstalledForDevClientBuildsAsync } from './utils/devClient';
|
||||
import { printBuildResults, printLogsUrls } from './utils/printBuildInfo';
|
||||
import { ensureRepoIsCleanAsync } from './utils/repository';
|
||||
|
||||
let metroConfigValidated = false;
|
||||
let sdkVersionChecked = false;
|
||||
|
||||
@@ -3,6 +3,7 @@ import { Errors } from '@oclif/core';
|
||||
import chalk from 'chalk';
|
||||
import resolveFrom from 'resolve-from';
|
||||
|
||||
import { reviewAndCommitChangesAsync } from './repository';
|
||||
import { toAppPlatform } from '../../graphql/types/AppPlatform';
|
||||
import Log, { learnMore } from '../../log';
|
||||
import { appPlatformDisplayNames } from '../../platform';
|
||||
@@ -11,7 +12,6 @@ import { confirmAsync } from '../../prompts';
|
||||
import { expoCommandAsync } from '../../utils/expoCli';
|
||||
import { ProfileData } from '../../utils/profiles';
|
||||
import { Client } from '../../vcs/vcs';
|
||||
import { reviewAndCommitChangesAsync } from './repository';
|
||||
|
||||
export async function ensureExpoDevClientInstalledForDevClientBuildsAsync({
|
||||
projectDir,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import chalk from 'chalk';
|
||||
|
||||
import { getBuildLogsUrl } from './url';
|
||||
import {
|
||||
AppPlatform,
|
||||
BuildFragment,
|
||||
@@ -7,7 +8,6 @@ import {
|
||||
} from '../../graphql/generated';
|
||||
import { appPlatformDisplayNames } from '../../platform';
|
||||
import formatFields from '../../utils/formatFields';
|
||||
import { getBuildLogsUrl } from './url';
|
||||
|
||||
export function formatGraphQLBuild(build: BuildFragment): string {
|
||||
const actor = getActorName(build);
|
||||
|
||||
@@ -2,6 +2,7 @@ import assert from 'assert';
|
||||
import indentString from 'indent-string';
|
||||
import qrcodeTerminal from 'qrcode-terminal';
|
||||
|
||||
import { getBuildLogsUrl, getInternalDistributionInstallUrl } from './url';
|
||||
import {
|
||||
AppPlatform,
|
||||
BuildError,
|
||||
@@ -13,7 +14,6 @@ import {
|
||||
} from '../../graphql/generated';
|
||||
import Log, { learnMore, link } from '../../log';
|
||||
import { appPlatformDisplayNames, appPlatformEmojis } from '../../platform';
|
||||
import { getBuildLogsUrl, getInternalDistributionInstallUrl } from './url';
|
||||
|
||||
function terminalLinkFallback(url: string, text: string): string {
|
||||
return `${text} (${url})`;
|
||||
|
||||
@@ -3,9 +3,9 @@ import chalk from 'chalk';
|
||||
import nullthrows from 'nullthrows';
|
||||
import semver from 'semver';
|
||||
|
||||
import { updateAppJsonConfigAsync } from './appJson';
|
||||
import Log from '../../log';
|
||||
import { promptAsync } from '../../prompts';
|
||||
import { updateAppJsonConfigAsync } from './appJson';
|
||||
|
||||
export function ensureStaticConfigExists(projectDir: string): void {
|
||||
const paths = getConfigFilePaths(projectDir);
|
||||
|
||||
@@ -4,9 +4,9 @@ import fs from 'fs-extra';
|
||||
import path from 'path';
|
||||
import semver from 'semver';
|
||||
|
||||
import { CommonContext } from './context';
|
||||
import Log, { learnMore } from '../log';
|
||||
import { isPNGAsync } from '../utils/image';
|
||||
import { CommonContext } from './context';
|
||||
|
||||
export function checkNodeEnvVariable(ctx: CommonContext<Platform>): void {
|
||||
if (ctx.buildProfile.env?.NODE_ENV === 'production') {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { testChannelBasicInfo } from './branch-mapping-fixtures';
|
||||
import {
|
||||
emptyBranchMapping,
|
||||
rolloutBranchMapping,
|
||||
@@ -13,7 +14,6 @@ import {
|
||||
isAlwaysTrueBranchMapping,
|
||||
isEmptyBranchMapping,
|
||||
} from '../branch-mapping';
|
||||
import { testChannelBasicInfo } from './branch-mapping-fixtures';
|
||||
|
||||
describe(assertVersion, () => {
|
||||
it('throws if the branch mapping is not the correct version', () => {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { format } from '@expo/timeago.js';
|
||||
|
||||
import { testChannelObject, testUpdateBranch1, testUpdateBranch2 } from './fixtures';
|
||||
import { getAlwaysTrueBranchMapping, getEmptyBranchMapping } from '../branch-mapping';
|
||||
import { getDescriptionByBranchId } from '../print-utils';
|
||||
import { testChannelObject, testUpdateBranch1, testUpdateBranch2 } from './fixtures';
|
||||
|
||||
describe(getDescriptionByBranchId, () => {
|
||||
it('should get descriptions for multiple branches with multiple update groups', () => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getUpdateBranch } from '../utils';
|
||||
import { channelInfoWithBranches, testBasicBranchInfo1 } from './branch-mapping-fixtures';
|
||||
import { getUpdateBranch } from '../utils';
|
||||
|
||||
describe(getUpdateBranch, () => {
|
||||
it('gets the update branch', () => {
|
||||
|
||||
@@ -41,7 +41,7 @@ export type AlwaysTrueBranchMapping = {
|
||||
{
|
||||
branchId: string;
|
||||
branchMappingLogic: BranchMappingAlwaysTrue;
|
||||
}
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import chalk from 'chalk';
|
||||
|
||||
import { assertVersion, hasEmptyBranchMap, hasStandardBranchMap } from './branch-mapping';
|
||||
import { UpdateChannelObject } from '../graphql/queries/ChannelQuery';
|
||||
import Log from '../log';
|
||||
import { getRollout, isRollout } from '../rollout/branch-mapping';
|
||||
@@ -8,7 +9,6 @@ import {
|
||||
formatBranch,
|
||||
getUpdateGroupDescriptionsWithBranch,
|
||||
} from '../update/utils';
|
||||
import { assertVersion, hasEmptyBranchMap, hasStandardBranchMap } from './branch-mapping';
|
||||
|
||||
/**
|
||||
* Log all the branches associated with the channel and their most recent update group
|
||||
@@ -38,31 +38,34 @@ export function logChannelDetails(channel: UpdateChannelObject): void {
|
||||
export function getDescriptionByBranchId(
|
||||
channel: UpdateChannelObject
|
||||
): Record<string, FormattedBranchDescription> {
|
||||
return channel.updateBranches.reduce((acc, branch) => {
|
||||
const maybeRollout = isRollout(channel) ? getRollout(channel) : null;
|
||||
let maybePercentOnBranch: number | undefined = undefined;
|
||||
if (maybeRollout) {
|
||||
maybePercentOnBranch =
|
||||
maybeRollout.rolledOutBranchId === branch.id
|
||||
? maybeRollout.percentRolledOut
|
||||
: 100 - maybeRollout.percentRolledOut;
|
||||
}
|
||||
return channel.updateBranches.reduce(
|
||||
(acc, branch) => {
|
||||
const maybeRollout = isRollout(channel) ? getRollout(channel) : null;
|
||||
let maybePercentOnBranch: number | undefined = undefined;
|
||||
if (maybeRollout) {
|
||||
maybePercentOnBranch =
|
||||
maybeRollout.rolledOutBranchId === branch.id
|
||||
? maybeRollout.percentRolledOut
|
||||
: 100 - maybeRollout.percentRolledOut;
|
||||
}
|
||||
|
||||
if (branch.updateGroups.length === 0) {
|
||||
acc[branch.id] = { branch: branch.name, branchRolloutPercentage: maybePercentOnBranch };
|
||||
if (branch.updateGroups.length === 0) {
|
||||
acc[branch.id] = { branch: branch.name, branchRolloutPercentage: maybePercentOnBranch };
|
||||
return acc;
|
||||
}
|
||||
const updateGroupsWithBranchDescriptions = getUpdateGroupDescriptionsWithBranch(
|
||||
branch.updateGroups
|
||||
);
|
||||
// display the most recent update group
|
||||
const updateGroupWithBranchDescription = updateGroupsWithBranchDescriptions[0];
|
||||
const { branch: branchName, ...updateGroup } = updateGroupWithBranchDescription;
|
||||
acc[branch.id] = {
|
||||
branch: branchName,
|
||||
branchRolloutPercentage: maybePercentOnBranch,
|
||||
update: updateGroup,
|
||||
};
|
||||
return acc;
|
||||
}
|
||||
const updateGroupsWithBranchDescriptions = getUpdateGroupDescriptionsWithBranch(
|
||||
branch.updateGroups
|
||||
);
|
||||
// display the most recent update group
|
||||
const updateGroupWithBranchDescription = updateGroupsWithBranchDescriptions[0];
|
||||
const { branch: branchName, ...updateGroup } = updateGroupWithBranchDescription;
|
||||
acc[branch.id] = {
|
||||
branch: branchName,
|
||||
branchRolloutPercentage: maybePercentOnBranch,
|
||||
update: updateGroup,
|
||||
};
|
||||
return acc;
|
||||
}, {} as Record<string, FormattedBranchDescription>);
|
||||
},
|
||||
{} as Record<string, FormattedBranchDescription>
|
||||
);
|
||||
}
|
||||
@@ -2,6 +2,9 @@ import chalk from 'chalk';
|
||||
import { print } from 'graphql';
|
||||
import gql from 'graphql-tag';
|
||||
|
||||
import { ChannelNotFoundError } from './errors';
|
||||
import { logChannelDetails } from './print-utils';
|
||||
import { ChannelBasicInfo } from './utils';
|
||||
import { createUpdateBranchOnAppAsync } from '../branch/queries';
|
||||
import { BranchNotFoundError } from '../branch/utils';
|
||||
import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
|
||||
@@ -24,9 +27,6 @@ import {
|
||||
paginatedQueryWithConfirmPromptAsync,
|
||||
paginatedQueryWithSelectPromptAsync,
|
||||
} from '../utils/queries';
|
||||
import { ChannelNotFoundError } from './errors';
|
||||
import { logChannelDetails } from './print-utils';
|
||||
import { ChannelBasicInfo } from './utils';
|
||||
|
||||
export const CHANNELS_LIMIT = 25;
|
||||
|
||||
|
||||
@@ -3,13 +3,6 @@ import { CombinedError } from '@urql/core';
|
||||
import { GraphQLError } from 'graphql/error';
|
||||
import nullthrows from 'nullthrows';
|
||||
|
||||
import {
|
||||
AnalyticsWithOrchestration,
|
||||
CommandEvent,
|
||||
createAnalyticsAsync,
|
||||
} from '../analytics/AnalyticsManager';
|
||||
import Log from '../log';
|
||||
import SessionManager from '../user/SessionManager';
|
||||
import AnalyticsContextField from './context/AnalyticsContextField';
|
||||
import ContextField from './context/ContextField';
|
||||
import {
|
||||
@@ -24,11 +17,18 @@ import ProjectDirContextField from './context/ProjectDirContextField';
|
||||
import SessionManagementContextField from './context/SessionManagementContextField';
|
||||
import VcsClientContextField from './context/VcsClientContextField';
|
||||
import { EasCommandError } from './errors';
|
||||
import {
|
||||
AnalyticsWithOrchestration,
|
||||
CommandEvent,
|
||||
createAnalyticsAsync,
|
||||
} from '../analytics/AnalyticsManager';
|
||||
import Log from '../log';
|
||||
import SessionManager from '../user/SessionManager';
|
||||
|
||||
export type ContextInput<
|
||||
T extends {
|
||||
[name: string]: any;
|
||||
} = object
|
||||
} = object,
|
||||
> = {
|
||||
[P in keyof T]: ContextField<T[P]>;
|
||||
};
|
||||
@@ -36,7 +36,7 @@ export type ContextInput<
|
||||
export type ContextOutput<
|
||||
T extends {
|
||||
[name: string]: any;
|
||||
} = object
|
||||
} = object,
|
||||
> = {
|
||||
[P in keyof T]: T[P];
|
||||
};
|
||||
@@ -136,7 +136,7 @@ export default abstract class EasCommand extends Command {
|
||||
protected async getContextAsync<
|
||||
C extends {
|
||||
[name: string]: any;
|
||||
} = object
|
||||
} = object,
|
||||
>(
|
||||
commandClass: { contextDefinition: ContextInput<C> },
|
||||
{ nonInteractive }: { nonInteractive: boolean }
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
import chalk from 'chalk';
|
||||
|
||||
import { ExpoGraphqlClient } from './context/contextUtils/createGraphqlClient';
|
||||
import {
|
||||
AppPlatform,
|
||||
Build,
|
||||
BuildFilter,
|
||||
BuildFragment,
|
||||
BuildStatus,
|
||||
InputMaybe,
|
||||
} from '../graphql/generated';
|
||||
import { BuildQuery } from '../graphql/queries/BuildQuery';
|
||||
import { RequestedPlatform, appPlatformEmojis } from '../platform';
|
||||
|
||||
const platformToAppPlatform: Record<
|
||||
Exclude<RequestedPlatform, RequestedPlatform.All>,
|
||||
AppPlatform
|
||||
> = {
|
||||
android: AppPlatform.Android,
|
||||
ios: AppPlatform.Ios,
|
||||
};
|
||||
|
||||
export async function ensureBuildExistsAsync(
|
||||
graphqlClient: ExpoGraphqlClient,
|
||||
buildId: string
|
||||
): Promise<void> {
|
||||
try {
|
||||
await BuildQuery.byIdAsync(graphqlClient, buildId);
|
||||
} catch {
|
||||
throw new Error(`Couldn't find a build matching the id ${buildId}`);
|
||||
}
|
||||
}
|
||||
|
||||
export async function fetchBuildsAsync({
|
||||
graphqlClient,
|
||||
projectId,
|
||||
filters,
|
||||
}: {
|
||||
graphqlClient: ExpoGraphqlClient;
|
||||
projectId: string;
|
||||
filters?: { statuses?: BuildStatus[]; platform?: RequestedPlatform; profile?: string };
|
||||
}): Promise<BuildFragment[]> {
|
||||
let builds: BuildFragment[];
|
||||
const queryFilters: InputMaybe<BuildFilter> = {};
|
||||
if (filters?.platform && filters.platform !== 'all') {
|
||||
queryFilters['platform'] = platformToAppPlatform[filters.platform];
|
||||
}
|
||||
if (filters?.profile) {
|
||||
queryFilters['buildProfile'] = filters.profile;
|
||||
}
|
||||
if (!filters?.statuses) {
|
||||
builds = await BuildQuery.viewBuildsOnAppAsync(graphqlClient, {
|
||||
appId: projectId,
|
||||
offset: 0,
|
||||
limit: 10,
|
||||
filter: queryFilters ? queryFilters : undefined,
|
||||
});
|
||||
} else {
|
||||
builds = (
|
||||
await Promise.all(
|
||||
filters.statuses.map(status =>
|
||||
BuildQuery.viewBuildsOnAppAsync(graphqlClient, {
|
||||
appId: projectId,
|
||||
offset: 0,
|
||||
limit: 10,
|
||||
filter: queryFilters ? { ...queryFilters, status } : { status },
|
||||
})
|
||||
)
|
||||
)
|
||||
).flat();
|
||||
}
|
||||
builds.sort((buildA, buildB) => (buildA.createdAt > buildB.createdAt ? -1 : 1));
|
||||
return builds;
|
||||
}
|
||||
|
||||
export function formatBuild(
|
||||
build: Pick<Build, 'id' | 'platform' | 'status' | 'createdAt'>
|
||||
): string {
|
||||
const platform = appPlatformEmojis[build.platform];
|
||||
const startTime = new Date(build.createdAt).toLocaleString();
|
||||
let statusText: string;
|
||||
if (build.status === BuildStatus.New) {
|
||||
statusText = 'new';
|
||||
} else if (build.status === BuildStatus.InQueue) {
|
||||
statusText = 'in queue';
|
||||
} else if (build.status === BuildStatus.InProgress) {
|
||||
statusText = 'in progress';
|
||||
} else if (build.status === BuildStatus.Finished) {
|
||||
statusText = 'finished';
|
||||
} else if (build.status === BuildStatus.Errored) {
|
||||
statusText = 'errored';
|
||||
} else if ([BuildStatus.PendingCancel, BuildStatus.Canceled].includes(build.status)) {
|
||||
statusText = 'canceled';
|
||||
} else {
|
||||
statusText = 'unknown';
|
||||
}
|
||||
const status = chalk.blue(statusText);
|
||||
return `${platform} Started at: ${startTime}, Status: ${status}, Id: ${build.id}`;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Analytics } from '../../analytics/AnalyticsManager';
|
||||
import ContextField, { ContextOptions } from './ContextField';
|
||||
import { Analytics } from '../../analytics/AnalyticsManager';
|
||||
|
||||
export default class AnalyticsContextField extends ContextField<Analytics> {
|
||||
async getValueAsync({ analytics }: ContextOptions): Promise<Analytics> {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { ExpoConfig } from '@expo/config-types';
|
||||
|
||||
import ContextField, { ContextOptions } from './ContextField';
|
||||
import { findProjectDirAndVerifyProjectSetupAsync } from './contextUtils/findProjectDirAndVerifyProjectSetupAsync';
|
||||
import { getProjectIdAsync } from './contextUtils/getProjectIdAsync';
|
||||
import {
|
||||
ExpoConfigOptions,
|
||||
getPrivateExpoConfig,
|
||||
getPublicExpoConfig,
|
||||
} from '../../project/expoConfig';
|
||||
import ContextField, { ContextOptions } from './ContextField';
|
||||
import { findProjectDirAndVerifyProjectSetupAsync } from './contextUtils/findProjectDirAndVerifyProjectSetupAsync';
|
||||
import { getProjectIdAsync } from './contextUtils/getProjectIdAsync';
|
||||
|
||||
export type DynamicConfigContextFn = (options?: ExpoConfigOptions) => Promise<{
|
||||
projectId: string;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import ContextField, { ContextOptions } from './ContextField';
|
||||
import { ExpoGraphqlClient, createGraphqlClient } from './contextUtils/createGraphqlClient';
|
||||
import { Actor } from '../../user/User';
|
||||
import FeatureGateEnvOverrides from '../gating/FeatureGateEnvOverrides';
|
||||
import FeatureGating from '../gating/FeatureGating';
|
||||
import ContextField, { ContextOptions } from './ContextField';
|
||||
import { ExpoGraphqlClient, createGraphqlClient } from './contextUtils/createGraphqlClient';
|
||||
|
||||
export default class LoggedInContextField extends ContextField<{
|
||||
actor: Actor;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import ContextField, { ContextOptions } from './ContextField';
|
||||
import { ExpoGraphqlClient, createGraphqlClient } from './contextUtils/createGraphqlClient';
|
||||
import { Actor } from '../../user/User';
|
||||
import FeatureGateEnvOverrides from '../gating/FeatureGateEnvOverrides';
|
||||
import FeatureGating from '../gating/FeatureGating';
|
||||
import ContextField, { ContextOptions } from './ContextField';
|
||||
import { ExpoGraphqlClient, createGraphqlClient } from './contextUtils/createGraphqlClient';
|
||||
|
||||
export default class MaybeLoggedInContextField extends ContextField<{
|
||||
actor: Actor | null;
|
||||
|
||||
+1
-1
@@ -1,10 +1,10 @@
|
||||
import { ExpoConfig } from '@expo/config-types';
|
||||
import { InvalidEasJsonError } from '@expo/eas-json/build/errors';
|
||||
|
||||
import { getPrivateExpoConfig } from '../../project/expoConfig';
|
||||
import ContextField, { ContextOptions } from './ContextField';
|
||||
import { findProjectDirAndVerifyProjectSetupAsync } from './contextUtils/findProjectDirAndVerifyProjectSetupAsync';
|
||||
import { getProjectIdAsync } from './contextUtils/getProjectIdAsync';
|
||||
import { getPrivateExpoConfig } from '../../project/expoConfig';
|
||||
|
||||
export class OptionalPrivateProjectConfigContextField extends ContextField<
|
||||
| {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { ExpoConfig } from '@expo/config-types';
|
||||
|
||||
import { getPrivateExpoConfig } from '../../project/expoConfig';
|
||||
import ContextField, { ContextOptions } from './ContextField';
|
||||
import { findProjectDirAndVerifyProjectSetupAsync } from './contextUtils/findProjectDirAndVerifyProjectSetupAsync';
|
||||
import { getProjectIdAsync } from './contextUtils/getProjectIdAsync';
|
||||
import { getPrivateExpoConfig } from '../../project/expoConfig';
|
||||
|
||||
export class PrivateProjectConfigContextField extends ContextField<{
|
||||
projectId: string;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import SessionManager from '../../user/SessionManager';
|
||||
import ContextField, { ContextOptions } from './ContextField';
|
||||
import SessionManager from '../../user/SessionManager';
|
||||
|
||||
export default class SessionManagementContextField extends ContextField<SessionManager> {
|
||||
async getValueAsync({ sessionManager }: ContextOptions): Promise<SessionManager> {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import ContextField from './ContextField';
|
||||
import { getVcsClient } from '../../vcs';
|
||||
import { Client } from '../../vcs/vcs';
|
||||
import ContextField from './ContextField';
|
||||
|
||||
export default class VcsClientContextField extends ContextField<Client> {
|
||||
async getValueAsync(): Promise<Client> {
|
||||
|
||||
@@ -3,6 +3,8 @@ import { ExpoConfig } from '@expo/config-types';
|
||||
import { Env } from '@expo/eas-build-job';
|
||||
import chalk from 'chalk';
|
||||
|
||||
import { createGraphqlClient } from './createGraphqlClient';
|
||||
import { findProjectRootAsync } from './findProjectDirAndVerifyProjectSetupAsync';
|
||||
import { AppQuery } from '../../../graphql/queries/AppQuery';
|
||||
import Log, { learnMore } from '../../../log';
|
||||
import { ora } from '../../../ora';
|
||||
@@ -11,8 +13,6 @@ import { fetchOrCreateProjectIDForWriteToConfigWithConfirmationAsync } from '../
|
||||
import { toAppPrivacy } from '../../../project/projectUtils';
|
||||
import SessionManager from '../../../user/SessionManager';
|
||||
import { Actor, getActorUsername } from '../../../user/User';
|
||||
import { createGraphqlClient } from './createGraphqlClient';
|
||||
import { findProjectRootAsync } from './findProjectDirAndVerifyProjectSetupAsync';
|
||||
|
||||
/**
|
||||
* Save an EAS project ID to the appropriate field in the app config.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import nullthrows from 'nullthrows';
|
||||
|
||||
import env from '../../env';
|
||||
import { FeatureGateKey } from './FeatureGateKey';
|
||||
import env from '../../env';
|
||||
|
||||
function parseFeatureGateEnvVariableValue(value: string | undefined): string[] {
|
||||
if (!value) {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import chalk from 'chalk';
|
||||
import { Flags } from '@oclif/core';
|
||||
import gql from 'graphql-tag';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import { ensureBuildExistsAsync, fetchBuildsAsync, formatBuild } from '../../commandUtils/builds';
|
||||
import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
|
||||
import { EASNonInteractiveFlag } from '../../commandUtils/flags';
|
||||
import { withErrorHandlingAsync } from '../../graphql/client';
|
||||
@@ -11,10 +12,9 @@ import {
|
||||
CancelBuildMutation,
|
||||
CancelBuildMutationVariables,
|
||||
} from '../../graphql/generated';
|
||||
import { BuildQuery } from '../../graphql/queries/BuildQuery';
|
||||
import Log from '../../log';
|
||||
import { ora } from '../../ora';
|
||||
import { appPlatformEmojis } from '../../platform';
|
||||
import { RequestedPlatform } from '../../platform';
|
||||
import { getDisplayNameForProjectIdAsync } from '../../project/projectUtils';
|
||||
import { confirmAsync, selectAsync } from '../../prompts';
|
||||
|
||||
@@ -42,54 +42,28 @@ async function cancelBuildAsync(
|
||||
return data.build!.cancel;
|
||||
}
|
||||
|
||||
function formatUnfinishedBuild(
|
||||
build: Pick<Build, 'id' | 'platform' | 'status' | 'createdAt'>
|
||||
): string {
|
||||
const platform = appPlatformEmojis[build.platform];
|
||||
const startTime = new Date(build.createdAt).toLocaleString();
|
||||
let statusText: string;
|
||||
if (build.status === BuildStatus.New) {
|
||||
statusText = 'new';
|
||||
} else if (build.status === BuildStatus.InQueue) {
|
||||
statusText = 'in queue';
|
||||
} else {
|
||||
statusText = 'in progress';
|
||||
}
|
||||
const status = chalk.blue(statusText);
|
||||
return `${platform} Started at: ${startTime}, Status: ${status}, Id: ${build.id}`;
|
||||
}
|
||||
|
||||
export async function selectBuildToCancelAsync(
|
||||
graphqlClient: ExpoGraphqlClient,
|
||||
projectId: string,
|
||||
projectDisplayName: string
|
||||
projectDisplayName: string,
|
||||
filters?: {
|
||||
platform?: RequestedPlatform;
|
||||
profile?: string;
|
||||
}
|
||||
): Promise<string | null> {
|
||||
const spinner = ora().start('Fetching the uncompleted builds…');
|
||||
|
||||
let builds;
|
||||
try {
|
||||
const [newBuilds, inQueueBuilds, inProgressBuilds] = await Promise.all([
|
||||
BuildQuery.viewBuildsOnAppAsync(graphqlClient, {
|
||||
appId: projectId,
|
||||
offset: 0,
|
||||
limit: 10,
|
||||
filter: { status: BuildStatus.New },
|
||||
}),
|
||||
BuildQuery.viewBuildsOnAppAsync(graphqlClient, {
|
||||
appId: projectId,
|
||||
offset: 0,
|
||||
limit: 10,
|
||||
filter: { status: BuildStatus.InQueue },
|
||||
}),
|
||||
BuildQuery.viewBuildsOnAppAsync(graphqlClient, {
|
||||
appId: projectId,
|
||||
offset: 0,
|
||||
limit: 10,
|
||||
filter: { status: BuildStatus.InProgress },
|
||||
}),
|
||||
]);
|
||||
builds = await fetchBuildsAsync({
|
||||
graphqlClient,
|
||||
projectId,
|
||||
filters: {
|
||||
...filters,
|
||||
statuses: [BuildStatus.New, BuildStatus.InQueue, BuildStatus.InProgress],
|
||||
},
|
||||
});
|
||||
spinner.stop();
|
||||
builds = [...newBuilds, ...inQueueBuilds, ...inProgressBuilds];
|
||||
} catch (error) {
|
||||
spinner.fail(
|
||||
`Something went wrong and we couldn't fetch the builds for the project ${projectDisplayName}.`
|
||||
@@ -97,13 +71,13 @@ export async function selectBuildToCancelAsync(
|
||||
throw error;
|
||||
}
|
||||
if (builds.length === 0) {
|
||||
Log.warn(`There aren't any uncompleted builds for the project ${projectDisplayName}.`);
|
||||
Log.warn(`We couldn't find any uncompleted builds for the project ${projectDisplayName}.`);
|
||||
return null;
|
||||
} else {
|
||||
const buildId = await selectAsync<string>(
|
||||
'Which build do you want to cancel?',
|
||||
builds.map(build => ({
|
||||
title: formatUnfinishedBuild(build),
|
||||
title: formatBuild(build),
|
||||
value: build.id,
|
||||
}))
|
||||
);
|
||||
@@ -116,17 +90,6 @@ export async function selectBuildToCancelAsync(
|
||||
}
|
||||
}
|
||||
|
||||
async function ensureBuildExistsAsync(
|
||||
graphqlClient: ExpoGraphqlClient,
|
||||
buildId: string
|
||||
): Promise<void> {
|
||||
try {
|
||||
await BuildQuery.byIdAsync(graphqlClient, buildId);
|
||||
} catch {
|
||||
throw new Error(`Couldn't find a build matching the id ${buildId}`);
|
||||
}
|
||||
}
|
||||
|
||||
export default class BuildCancel extends EasCommand {
|
||||
static override description = 'cancel a build';
|
||||
|
||||
@@ -134,6 +97,16 @@ export default class BuildCancel extends EasCommand {
|
||||
|
||||
static override flags = {
|
||||
...EASNonInteractiveFlag,
|
||||
platform: Flags.enum({
|
||||
char: 'p',
|
||||
description: 'Filter builds by the platform if build ID is not provided',
|
||||
options: Object.values(RequestedPlatform),
|
||||
}),
|
||||
profile: Flags.string({
|
||||
char: 'e',
|
||||
description: 'Filter builds by build profile if build ID is not provided',
|
||||
helpValue: 'PROFILE_NAME',
|
||||
}),
|
||||
};
|
||||
|
||||
static override contextDefinition = {
|
||||
@@ -145,8 +118,15 @@ export default class BuildCancel extends EasCommand {
|
||||
async runAsync(): Promise<void> {
|
||||
const {
|
||||
args: { BUILD_ID: buildIdFromArg },
|
||||
flags: { 'non-interactive': nonInteractive },
|
||||
flags: { 'non-interactive': nonInteractive, platform, profile },
|
||||
} = await this.parse(BuildCancel);
|
||||
|
||||
if (buildIdFromArg && (platform || profile)) {
|
||||
throw new Error(
|
||||
'Build ID cannot be used together with platform and profile flags. They are used to filter the list of builds when not providing the build ID'
|
||||
);
|
||||
}
|
||||
|
||||
const {
|
||||
privateProjectConfig: { projectId },
|
||||
loggedIn: { graphqlClient },
|
||||
@@ -163,10 +143,13 @@ export default class BuildCancel extends EasCommand {
|
||||
let buildId: string | null = buildIdFromArg;
|
||||
if (!buildId) {
|
||||
if (nonInteractive) {
|
||||
throw new Error('BUILD_ID must not be empty in non-interactive mode');
|
||||
throw new Error('Build ID must be provided in non-interactive mode');
|
||||
}
|
||||
|
||||
buildId = await selectBuildToCancelAsync(graphqlClient, projectId, displayName);
|
||||
buildId = await selectBuildToCancelAsync(graphqlClient, projectId, displayName, {
|
||||
platform,
|
||||
profile,
|
||||
});
|
||||
if (!buildId) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
import { Flags } from '@oclif/core';
|
||||
import gql from 'graphql-tag';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import { ensureBuildExistsAsync, fetchBuildsAsync, formatBuild } from '../../commandUtils/builds';
|
||||
import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
|
||||
import { EASNonInteractiveFlag } from '../../commandUtils/flags';
|
||||
import { withErrorHandlingAsync } from '../../graphql/client';
|
||||
import { Build, DeleteBuildMutation, DeleteBuildMutationVariables } from '../../graphql/generated';
|
||||
import Log from '../../log';
|
||||
import { ora } from '../../ora';
|
||||
import { RequestedPlatform } from '../../platform';
|
||||
import { getDisplayNameForProjectIdAsync } from '../../project/projectUtils';
|
||||
import { confirmAsync, selectAsync } from '../../prompts';
|
||||
|
||||
async function deleteBuildAsync(
|
||||
graphqlClient: ExpoGraphqlClient,
|
||||
buildId: string
|
||||
): Promise<Pick<Build, 'id'>> {
|
||||
const data = await withErrorHandlingAsync(
|
||||
graphqlClient
|
||||
.mutation<DeleteBuildMutation, DeleteBuildMutationVariables>(
|
||||
gql`
|
||||
mutation DeleteBuildMutation($buildId: ID!) {
|
||||
build(buildId: $buildId) {
|
||||
deleteBuild(buildId: $buildId) {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
{ buildId }
|
||||
)
|
||||
.toPromise()
|
||||
);
|
||||
return data.build!.deleteBuild;
|
||||
}
|
||||
|
||||
export async function selectBuildToDeleteAsync(
|
||||
graphqlClient: ExpoGraphqlClient,
|
||||
projectId: string,
|
||||
projectDisplayName: string,
|
||||
filters?: {
|
||||
platform?: RequestedPlatform;
|
||||
profile?: string;
|
||||
}
|
||||
): Promise<string | null> {
|
||||
const spinner = ora().start('Fetching builds…');
|
||||
|
||||
let builds;
|
||||
try {
|
||||
builds = await fetchBuildsAsync({ graphqlClient, projectId, filters });
|
||||
spinner.stop();
|
||||
} catch (error) {
|
||||
spinner.fail(
|
||||
`Something went wrong and we couldn't fetch the builds for the project ${projectDisplayName}.`
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
if (builds.length === 0) {
|
||||
Log.warn(`We couldn't find any builds for the project ${projectDisplayName}.`);
|
||||
return null;
|
||||
} else {
|
||||
const buildId = await selectAsync<string>(
|
||||
'Which build do you want to delete?',
|
||||
builds.map(build => ({
|
||||
title: formatBuild(build),
|
||||
value: build.id,
|
||||
}))
|
||||
);
|
||||
|
||||
return (await confirmAsync({
|
||||
message: 'Are you sure you want to delete it?',
|
||||
}))
|
||||
? buildId
|
||||
: null;
|
||||
}
|
||||
}
|
||||
|
||||
export default class BuildDelete extends EasCommand {
|
||||
static override description = 'delete a build';
|
||||
static override args = [{ name: 'BUILD_ID' }];
|
||||
static override flags = {
|
||||
...EASNonInteractiveFlag,
|
||||
platform: Flags.enum({
|
||||
char: 'p',
|
||||
description: 'Filter builds by the platform if build ID is not provided',
|
||||
options: Object.values(RequestedPlatform),
|
||||
}),
|
||||
profile: Flags.string({
|
||||
char: 'e',
|
||||
description: 'Filter builds by build profile if build ID is not provided',
|
||||
helpValue: 'PROFILE_NAME',
|
||||
}),
|
||||
};
|
||||
static override contextDefinition = {
|
||||
...this.ContextOptions.ProjectConfig,
|
||||
...this.ContextOptions.LoggedIn,
|
||||
...this.ContextOptions.Vcs,
|
||||
};
|
||||
|
||||
async runAsync(): Promise<void> {
|
||||
const {
|
||||
args: { BUILD_ID: buildIdFromArg },
|
||||
flags: { 'non-interactive': nonInteractive, platform, profile },
|
||||
} = await this.parse(BuildDelete);
|
||||
|
||||
if (buildIdFromArg && (platform || profile)) {
|
||||
throw new Error(
|
||||
'Build ID cannot be used together with platform and profile flags. They are used to filter the list of builds when not providing the build ID'
|
||||
);
|
||||
}
|
||||
|
||||
const {
|
||||
privateProjectConfig: { projectId },
|
||||
loggedIn: { graphqlClient },
|
||||
} = await this.getContextAsync(BuildDelete, { nonInteractive });
|
||||
const displayName = await getDisplayNameForProjectIdAsync(graphqlClient, projectId);
|
||||
|
||||
if (buildIdFromArg) {
|
||||
await ensureBuildExistsAsync(graphqlClient, buildIdFromArg);
|
||||
}
|
||||
|
||||
let buildId: string | null = buildIdFromArg;
|
||||
if (!buildId) {
|
||||
if (nonInteractive) {
|
||||
throw new Error('Build ID must be provided in non-interactive mode');
|
||||
}
|
||||
|
||||
buildId = await selectBuildToDeleteAsync(graphqlClient, projectId, displayName, {
|
||||
platform,
|
||||
profile,
|
||||
});
|
||||
if (!buildId) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const spinner = ora().start('Deleting the build...');
|
||||
try {
|
||||
await deleteBuildAsync(graphqlClient, buildId);
|
||||
spinner.succeed('Build deleted');
|
||||
} catch (error) {
|
||||
spinner.fail(`Something went wrong and we couldn't delete your build ${buildId}`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,9 +50,7 @@ export default class Config extends EasCommand {
|
||||
maybeProfile ??
|
||||
(await selectAsync(
|
||||
'Select build profile',
|
||||
(
|
||||
await EasJsonUtils.getBuildProfileNamesAsync(accessor)
|
||||
).map(profileName => ({
|
||||
(await EasJsonUtils.getBuildProfileNamesAsync(accessor)).map(profileName => ({
|
||||
title: profileName,
|
||||
value: profileName,
|
||||
}))
|
||||
|
||||
@@ -37,7 +37,6 @@ export default class Open extends EasCommand {
|
||||
} else {
|
||||
spinner.fail(failedMessage);
|
||||
}
|
||||
return;
|
||||
} catch (error) {
|
||||
spinner.fail(failedMessage);
|
||||
throw error;
|
||||
|
||||
@@ -293,7 +293,12 @@ async function askUpdatesFromChannelNameAsync(
|
||||
nonInteractive,
|
||||
}: { projectId: string; channelName: string; json: boolean; nonInteractive: boolean }
|
||||
): Promise<UpdateToRepublish[]> {
|
||||
const branchName = await getBranchNameFromChannelNameAsync(graphqlClient, projectId, channelName);
|
||||
const branchName = await getBranchNameFromChannelNameAsync(
|
||||
graphqlClient,
|
||||
projectId,
|
||||
channelName,
|
||||
{ json, nonInteractive, offset: 0 }
|
||||
);
|
||||
|
||||
return await askUpdatesFromBranchNameAsync(graphqlClient, {
|
||||
projectId,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Flags } from '@oclif/core';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import { promptAsync } from '../../prompts';
|
||||
import UpdateRepublish from './republish';
|
||||
import UpdateRollBackToEmbedded from './roll-back-to-embedded';
|
||||
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';
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
import {
|
||||
testKeystore2Base64,
|
||||
testKeystoreBase64,
|
||||
testPKCS12KeystoreBase64,
|
||||
testPKCS12KeystoreEmptyPasswordBase64,
|
||||
} from './fixtures-base64-data';
|
||||
import {
|
||||
AndroidAppBuildCredentialsFragment,
|
||||
AndroidFcmFragment,
|
||||
@@ -11,12 +17,6 @@ import {
|
||||
} from '../../graphql/generated';
|
||||
import * as AndroidGraphqlClient from '../android/api/GraphqlClient';
|
||||
import { Keystore } from '../android/credentials';
|
||||
import {
|
||||
testKeystore2Base64,
|
||||
testKeystoreBase64,
|
||||
testPKCS12KeystoreBase64,
|
||||
testPKCS12KeystoreEmptyPasswordBase64,
|
||||
} from './fixtures-base64-data';
|
||||
|
||||
const now = new Date();
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import merge from 'ts-deepmerge';
|
||||
|
||||
import { CredentialsContext } from '../context';
|
||||
import { getNewAndroidApiMock } from './fixtures-android';
|
||||
import { getAppstoreMock } from './fixtures-appstore';
|
||||
import { testAppJson, testUsername } from './fixtures-constants';
|
||||
import { getNewIosApiMock } from './fixtures-ios';
|
||||
import { CredentialsContext } from '../context';
|
||||
|
||||
export function createCtxMock(mockOverride: Record<string, any> = {}): CredentialsContext {
|
||||
const defaultMock = {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { UserRole } from '@expo/apple-utils';
|
||||
|
||||
import { testProvisioningProfileBase64 } from './fixtures-base64-data';
|
||||
import {
|
||||
AppFragment,
|
||||
AppStoreConnectApiKeyFragment,
|
||||
@@ -21,7 +22,6 @@ import {
|
||||
ProvisioningProfile,
|
||||
} from '../ios/appstore/Credentials.types';
|
||||
import { Target } from '../ios/types';
|
||||
import { testProvisioningProfileBase64 } from './fixtures-base64-data';
|
||||
|
||||
const now = new Date();
|
||||
|
||||
|
||||
@@ -2,12 +2,12 @@ import { Platform } from '@expo/eas-build-job';
|
||||
import { CredentialsSource } from '@expo/eas-json';
|
||||
import nullthrows from 'nullthrows';
|
||||
|
||||
import { AndroidAppBuildCredentialsFragment } from '../../graphql/generated';
|
||||
import { CredentialsContext } from '../context';
|
||||
import * as credentialsJsonReader from '../credentialsJson/read';
|
||||
import { SetUpBuildCredentials } from './actions/SetUpBuildCredentials';
|
||||
import { AppLookupParams } from './api/GraphqlClient';
|
||||
import { Keystore } from './credentials';
|
||||
import { AndroidAppBuildCredentialsFragment } from '../../graphql/generated';
|
||||
import { CredentialsContext } from '../context';
|
||||
import * as credentialsJsonReader from '../credentialsJson/read';
|
||||
|
||||
export interface AndroidCredentials {
|
||||
keystore: Keystore;
|
||||
@@ -20,7 +20,10 @@ interface Options {
|
||||
export default class AndroidCredentialsProvider {
|
||||
public readonly platform = Platform.ANDROID;
|
||||
|
||||
constructor(private ctx: CredentialsContext, private options: Options) {}
|
||||
constructor(
|
||||
private ctx: CredentialsContext,
|
||||
private options: Options
|
||||
) {}
|
||||
|
||||
public async getCredentialsAsync(
|
||||
src: CredentialsSource.LOCAL | CredentialsSource.REMOTE
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import chalk from 'chalk';
|
||||
|
||||
import { BackupKeystore } from './DownloadKeystore';
|
||||
import { AndroidAppBuildCredentialsFragment } from '../../../graphql/generated';
|
||||
import Log from '../../../log';
|
||||
import { confirmAsync } from '../../../prompts';
|
||||
import { CredentialsContext } from '../../context';
|
||||
import { AppLookupParams } from '../api/GraphqlClient';
|
||||
import { BackupKeystore } from './DownloadKeystore';
|
||||
|
||||
export class RemoveKeystore {
|
||||
constructor(private app: AppLookupParams) {}
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import nullthrows from 'nullthrows';
|
||||
|
||||
import {
|
||||
canCopyLegacyCredentialsAsync,
|
||||
createOrUpdateDefaultAndroidAppBuildCredentialsAsync,
|
||||
promptUserAndCopyLegacyCredentialsAsync,
|
||||
} from './BuildCredentialsUtils';
|
||||
import { CreateKeystore } from './CreateKeystore';
|
||||
import {
|
||||
AndroidAppBuildCredentialsFragment,
|
||||
AndroidKeystoreFragment,
|
||||
@@ -9,12 +15,6 @@ import { ora } from '../../../ora';
|
||||
import { CredentialsContext } from '../../context';
|
||||
import { MissingCredentialsNonInteractiveError } from '../../errors';
|
||||
import { AppLookupParams } from '../api/GraphqlClient';
|
||||
import {
|
||||
canCopyLegacyCredentialsAsync,
|
||||
createOrUpdateDefaultAndroidAppBuildCredentialsAsync,
|
||||
promptUserAndCopyLegacyCredentialsAsync,
|
||||
} from './BuildCredentialsUtils';
|
||||
import { CreateKeystore } from './CreateKeystore';
|
||||
|
||||
interface Options {
|
||||
app: AppLookupParams;
|
||||
|
||||
+1
-1
@@ -1,3 +1,4 @@
|
||||
import { BackupKeystore } from './DownloadKeystore';
|
||||
import {
|
||||
AndroidAppBuildCredentialsFragment,
|
||||
AndroidKeystoreType,
|
||||
@@ -12,7 +13,6 @@ import {
|
||||
} from '../../manager/SelectAndroidBuildCredentials';
|
||||
import { AppLookupParams } from '../api/GraphqlClient';
|
||||
import { getKeystoreWithType } from '../utils/keystoreNew';
|
||||
import { BackupKeystore } from './DownloadKeystore';
|
||||
|
||||
export class SetUpBuildCredentialsFromCredentialsJson {
|
||||
constructor(private app: AppLookupParams) {}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import nullthrows from 'nullthrows';
|
||||
|
||||
import { AssignGoogleServiceAccountKey } from './AssignGoogleServiceAccountKey';
|
||||
import { CreateGoogleServiceAccountKey } from './CreateGoogleServiceAccountKey';
|
||||
import { UseExistingGoogleServiceAccountKey } from './UseExistingGoogleServiceAccountKey';
|
||||
import {
|
||||
CommonAndroidAppCredentialsFragment,
|
||||
GoogleServiceAccountKeyFragment,
|
||||
@@ -9,9 +12,6 @@ import { promptAsync } from '../../../prompts';
|
||||
import { CredentialsContext } from '../../context';
|
||||
import { MissingCredentialsNonInteractiveError } from '../../errors';
|
||||
import { AppLookupParams } from '../api/GraphqlClient';
|
||||
import { AssignGoogleServiceAccountKey } from './AssignGoogleServiceAccountKey';
|
||||
import { CreateGoogleServiceAccountKey } from './CreateGoogleServiceAccountKey';
|
||||
import { UseExistingGoogleServiceAccountKey } from './UseExistingGoogleServiceAccountKey';
|
||||
|
||||
export class SetUpGoogleServiceAccountKey {
|
||||
constructor(private app: AppLookupParams) {}
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
import { AndroidAppBuildCredentialsMutation } from './graphql/mutations/AndroidAppBuildCredentialsMutation';
|
||||
import { AndroidAppCredentialsMutation } from './graphql/mutations/AndroidAppCredentialsMutation';
|
||||
import { AndroidFcmMutation } from './graphql/mutations/AndroidFcmMutation';
|
||||
import { AndroidKeystoreMutation } from './graphql/mutations/AndroidKeystoreMutation';
|
||||
import { GoogleServiceAccountKeyMutation } from './graphql/mutations/GoogleServiceAccountKeyMutation';
|
||||
import { AndroidAppCredentialsQuery } from './graphql/queries/AndroidAppCredentialsQuery';
|
||||
import { GoogleServiceAccountKeyQuery } from './graphql/queries/GoogleServiceAccountKeyQuery';
|
||||
import { ExpoGraphqlClient } from '../../../commandUtils/context/contextUtils/createGraphqlClient';
|
||||
import {
|
||||
AccountFragment,
|
||||
@@ -11,13 +18,6 @@ import {
|
||||
} from '../../../graphql/generated';
|
||||
import { AppQuery } from '../../../graphql/queries/AppQuery';
|
||||
import { GoogleServiceAccountKey, KeystoreWithType } from '../credentials';
|
||||
import { AndroidAppBuildCredentialsMutation } from './graphql/mutations/AndroidAppBuildCredentialsMutation';
|
||||
import { AndroidAppCredentialsMutation } from './graphql/mutations/AndroidAppCredentialsMutation';
|
||||
import { AndroidFcmMutation } from './graphql/mutations/AndroidFcmMutation';
|
||||
import { AndroidKeystoreMutation } from './graphql/mutations/AndroidKeystoreMutation';
|
||||
import { GoogleServiceAccountKeyMutation } from './graphql/mutations/GoogleServiceAccountKeyMutation';
|
||||
import { AndroidAppCredentialsQuery } from './graphql/queries/AndroidAppCredentialsQuery';
|
||||
import { GoogleServiceAccountKeyQuery } from './graphql/queries/GoogleServiceAccountKeyQuery';
|
||||
|
||||
export interface AppLookupParams {
|
||||
account: AccountFragment;
|
||||
|
||||
@@ -3,6 +3,10 @@ import { Env } from '@expo/eas-build-job';
|
||||
import { EasJson } from '@expo/eas-json';
|
||||
import chalk from 'chalk';
|
||||
|
||||
import * as AndroidGraphqlClient from './android/api/GraphqlClient';
|
||||
import * as IosGraphqlClient from './ios/api/GraphqlClient';
|
||||
import AppStoreApi from './ios/appstore/AppStoreApi';
|
||||
import { AuthenticationMode } from './ios/appstore/authenticateTypes';
|
||||
import { Analytics } from '../analytics/AnalyticsManager';
|
||||
import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
|
||||
import Log from '../log';
|
||||
@@ -10,10 +14,6 @@ import { getPrivateExpoConfig } from '../project/expoConfig';
|
||||
import { confirmAsync } from '../prompts';
|
||||
import { Actor } from '../user/User';
|
||||
import { Client } from '../vcs/vcs';
|
||||
import * as AndroidGraphqlClient from './android/api/GraphqlClient';
|
||||
import * as IosGraphqlClient from './ios/api/GraphqlClient';
|
||||
import AppStoreApi from './ios/appstore/AppStoreApi';
|
||||
import { AuthenticationMode } from './ios/appstore/authenticateTypes';
|
||||
|
||||
export type CredentialsContextProjectInfo = {
|
||||
exp: ExpoConfig;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import fs from 'fs-extra';
|
||||
import path from 'path';
|
||||
|
||||
import { Target } from '../ios/types';
|
||||
import {
|
||||
AndroidCredentials,
|
||||
CredentialsJson,
|
||||
@@ -12,6 +11,7 @@ import {
|
||||
IosTargetCredentials,
|
||||
} from './types';
|
||||
import { getCredentialsJsonPath } from './utils';
|
||||
import { Target } from '../ios/types';
|
||||
|
||||
export async function readAndroidCredentialsAsync(projectDir: string): Promise<AndroidCredentials> {
|
||||
const credentialsJson = await readAsync(projectDir);
|
||||
|
||||
@@ -2,6 +2,13 @@ import fs from 'fs-extra';
|
||||
import nullthrows from 'nullthrows';
|
||||
import path from 'path';
|
||||
|
||||
import { readRawAsync } from './read';
|
||||
import {
|
||||
CredentialsJson,
|
||||
CredentialsJsonIosCredentials,
|
||||
CredentialsJsonIosTargetCredentials,
|
||||
} from './types';
|
||||
import { getCredentialsJsonPath } from './utils';
|
||||
import { AndroidAppBuildCredentialsFragment, IosDistributionType } from '../../graphql/generated';
|
||||
import Log from '../../log';
|
||||
import { findApplicationTarget, findTargetByName } from '../../project/ios/target';
|
||||
@@ -10,13 +17,6 @@ import GitClient from '../../vcs/clients/git';
|
||||
import { Client } from '../../vcs/vcs';
|
||||
import { CredentialsContext } from '../context';
|
||||
import { App, Target, TargetCredentials } from '../ios/types';
|
||||
import { readRawAsync } from './read';
|
||||
import {
|
||||
CredentialsJson,
|
||||
CredentialsJsonIosCredentials,
|
||||
CredentialsJsonIosTargetCredentials,
|
||||
} from './types';
|
||||
import { getCredentialsJsonPath } from './utils';
|
||||
|
||||
/**
|
||||
* Update Android credentials.json with values from www, content of credentials.json
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import path from 'path';
|
||||
|
||||
import { Target } from '../ios/types';
|
||||
import { IosCredentials } from './types';
|
||||
import { Target } from '../ios/types';
|
||||
|
||||
export function getCredentialsJsonPath(projectDir: string): string {
|
||||
return path.join(projectDir, 'credentials.json');
|
||||
|
||||
@@ -11,7 +11,10 @@ export class MissingCredentialsError extends Error {
|
||||
}
|
||||
|
||||
export class UnsupportedCredentialsChoiceError extends Error {
|
||||
constructor(message: string, public choice: string) {
|
||||
constructor(
|
||||
message: string,
|
||||
public choice: string
|
||||
) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,11 @@ import {
|
||||
IosEnterpriseProvisioning,
|
||||
} from '@expo/eas-json';
|
||||
|
||||
import { getAppFromContextAsync } from './actions/BuildCredentialsUtils';
|
||||
import { SetUpBuildCredentials } from './actions/SetUpBuildCredentials';
|
||||
import { SetUpPushKey } from './actions/SetUpPushKey';
|
||||
import { App, IosCredentials, Target } from './types';
|
||||
import { isAdHocProfile, isEnterpriseUniversalProfile } from './utils/provisioningProfile';
|
||||
import { CommonIosAppCredentialsFragment } from '../../graphql/generated';
|
||||
import Log from '../../log';
|
||||
import { findApplicationTarget } from '../../project/ios/target';
|
||||
@@ -13,11 +18,6 @@ import { selectAsync } from '../../prompts';
|
||||
import { CredentialsContext } from '../context';
|
||||
import * as credentialsJsonReader from '../credentialsJson/read';
|
||||
import { ensureAllTargetsAreConfigured } from '../credentialsJson/utils';
|
||||
import { getAppFromContextAsync } from './actions/BuildCredentialsUtils';
|
||||
import { SetUpBuildCredentials } from './actions/SetUpBuildCredentials';
|
||||
import { SetUpPushKey } from './actions/SetUpPushKey';
|
||||
import { App, IosCredentials, Target } from './types';
|
||||
import { isAdHocProfile, isEnterpriseUniversalProfile } from './utils/provisioningProfile';
|
||||
|
||||
interface Options {
|
||||
app: App;
|
||||
@@ -35,7 +35,10 @@ enum PushNotificationSetupOption {
|
||||
export default class IosCredentialsProvider {
|
||||
public readonly platform = Platform.IOS;
|
||||
|
||||
constructor(private ctx: CredentialsContext, private options: Options) {}
|
||||
constructor(
|
||||
private ctx: CredentialsContext,
|
||||
private options: Options
|
||||
) {}
|
||||
|
||||
public async getCredentialsAsync(
|
||||
src: CredentialsSource.LOCAL | CredentialsSource.REMOTE
|
||||
|
||||
@@ -3,6 +3,7 @@ import fs from 'fs-extra';
|
||||
import { nanoid } from 'nanoid';
|
||||
import path from 'path';
|
||||
|
||||
import { formatAppleTeam } from './AppleTeamFormatting';
|
||||
import { AccountFragment, AppStoreConnectApiKeyFragment } from '../../../graphql/generated';
|
||||
import Log, { learnMore } from '../../../log';
|
||||
import { confirmAsync, promptAsync } from '../../../prompts';
|
||||
@@ -20,7 +21,6 @@ import {
|
||||
ascApiKeyIssuerIdSchema,
|
||||
} from '../credentials';
|
||||
import { isAscApiKeyValidAndTrackedAsync } from '../validators/validateAscApiKey';
|
||||
import { formatAppleTeam } from './AppleTeamFormatting';
|
||||
|
||||
export enum AppStoreApiKeyPurpose {
|
||||
SUBMISSION_SERVICE = 'EAS Submit',
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { resolveAppleTeamIfAuthenticatedAsync } from './AppleTeamUtils';
|
||||
import { AppStoreApiKeyPurpose } from './AscApiKeyUtils';
|
||||
import {
|
||||
AppStoreConnectApiKeyFragment,
|
||||
CommonIosAppCredentialsFragment,
|
||||
@@ -5,8 +7,6 @@ import {
|
||||
import Log from '../../../log';
|
||||
import { CredentialsContext } from '../../context';
|
||||
import { AppLookupParams } from '../api/graphql/types/AppLookupParams';
|
||||
import { resolveAppleTeamIfAuthenticatedAsync } from './AppleTeamUtils';
|
||||
import { AppStoreApiKeyPurpose } from './AscApiKeyUtils';
|
||||
|
||||
export class AssignAscApiKey {
|
||||
constructor(private app: AppLookupParams) {}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { resolveAppleTeamIfAuthenticatedAsync } from './AppleTeamUtils';
|
||||
import { ApplePushKeyFragment, CommonIosAppCredentialsFragment } from '../../../graphql/generated';
|
||||
import Log from '../../../log';
|
||||
import { CredentialsContext } from '../../context';
|
||||
import { AppLookupParams } from '../api/graphql/types/AppLookupParams';
|
||||
import { resolveAppleTeamIfAuthenticatedAsync } from './AppleTeamUtils';
|
||||
|
||||
export class AssignPushKey {
|
||||
constructor(private app: AppLookupParams) {}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import nullthrows from 'nullthrows';
|
||||
|
||||
import { resolveAppleTeamIfAuthenticatedAsync } from './AppleTeamUtils';
|
||||
import {
|
||||
AppleDistributionCertificateFragment,
|
||||
AppleProvisioningProfileFragment,
|
||||
@@ -11,7 +12,6 @@ import { getOwnerAccountForProjectIdAsync } from '../../../project/projectUtils'
|
||||
import { CredentialsContext } from '../../context';
|
||||
import { AppLookupParams } from '../api/graphql/types/AppLookupParams';
|
||||
import { App, Target } from '../types';
|
||||
import { resolveAppleTeamIfAuthenticatedAsync } from './AppleTeamUtils';
|
||||
|
||||
export async function getAllBuildCredentialsAsync(
|
||||
ctx: CredentialsContext,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { AppStoreApiKeyPurpose, provideOrGenerateAscApiKeyAsync } from './AscApiKeyUtils';
|
||||
import { AccountFragment, AppStoreConnectApiKeyFragment } from '../../../graphql/generated';
|
||||
import Log from '../../../log';
|
||||
import { CredentialsContext } from '../../context';
|
||||
import { AppStoreApiKeyPurpose, provideOrGenerateAscApiKeyAsync } from './AscApiKeyUtils';
|
||||
|
||||
export class CreateAscApiKey {
|
||||
constructor(private account: AccountFragment) {}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { provideOrGenerateDistributionCertificateAsync } from './DistributionCertificateUtils';
|
||||
import { AccountFragment } from '../../../graphql/generated';
|
||||
import Log from '../../../log';
|
||||
import { CredentialsContext } from '../../context';
|
||||
import { AppleDistributionCertificateMutationResult } from '../api/graphql/mutations/AppleDistributionCertificateMutation';
|
||||
import { provideOrGenerateDistributionCertificateAsync } from './DistributionCertificateUtils';
|
||||
|
||||
export class CreateDistributionCertificate {
|
||||
constructor(private account: AccountFragment) {}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import assert from 'assert';
|
||||
import nullthrows from 'nullthrows';
|
||||
|
||||
import { resolveAppleTeamIfAuthenticatedAsync } from './AppleTeamUtils';
|
||||
import { generateProvisioningProfileAsync } from './ProvisioningProfileUtils';
|
||||
import { AppleDistributionCertificateFragment } from '../../../graphql/generated';
|
||||
import Log from '../../../log';
|
||||
import { CredentialsContext } from '../../context';
|
||||
@@ -12,8 +14,6 @@ import { ProvisioningProfile } from '../appstore/Credentials.types';
|
||||
import { AuthCtx } from '../appstore/authenticateTypes';
|
||||
import { provisioningProfileSchema } from '../credentials';
|
||||
import { Target } from '../types';
|
||||
import { resolveAppleTeamIfAuthenticatedAsync } from './AppleTeamUtils';
|
||||
import { generateProvisioningProfileAsync } from './ProvisioningProfileUtils';
|
||||
|
||||
export class CreateProvisioningProfile {
|
||||
constructor(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { provideOrGeneratePushKeyAsync } from './PushKeyUtils';
|
||||
import { AccountFragment, ApplePushKeyFragment } from '../../../graphql/generated';
|
||||
import Log from '../../../log';
|
||||
import { CredentialsContext } from '../../context';
|
||||
import { provideOrGeneratePushKeyAsync } from './PushKeyUtils';
|
||||
|
||||
export class CreatePushKey {
|
||||
constructor(private account: AccountFragment) {}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { promptAsync } from '../.././../prompts';
|
||||
import { AppleDevice, AppleDeviceFragment } from '../../../graphql/generated';
|
||||
import { APPLE_DEVICE_CLASS_LABELS } from '../../../graphql/types/credentials/AppleDevice';
|
||||
import { promptAsync } from '../.././../prompts';
|
||||
|
||||
export async function chooseDevicesAsync(
|
||||
allDevices: AppleDeviceFragment[],
|
||||
|
||||
@@ -2,6 +2,7 @@ import assert from 'assert';
|
||||
import chalk from 'chalk';
|
||||
import dateformat from 'dateformat';
|
||||
|
||||
import { formatAppleTeam } from './AppleTeamFormatting';
|
||||
import { AccountFragment, AppleDistributionCertificateFragment } from '../../../graphql/generated';
|
||||
import Log, { learnMore } from '../../../log';
|
||||
import { promptAsync } from '../../../prompts';
|
||||
@@ -17,7 +18,6 @@ import { filterRevokedDistributionCertsFromEasServers } from '../appstore/Creden
|
||||
import { AppleTooManyCertsError } from '../appstore/distributionCertificate';
|
||||
import { distributionCertificateSchema } from '../credentials';
|
||||
import { validateDistributionCertificateAsync } from '../validators/validateDistributionCertificate';
|
||||
import { formatAppleTeam } from './AppleTeamFormatting';
|
||||
|
||||
export function formatDistributionCertificate(
|
||||
distributionCertificate: AppleDistributionCertificateFragment,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import chalk from 'chalk';
|
||||
|
||||
import { formatAppleTeam } from './AppleTeamFormatting';
|
||||
import { AccountFragment, ApplePushKeyFragment } from '../../../graphql/generated';
|
||||
import Log, { learnMore } from '../../../log';
|
||||
import { confirmAsync, promptAsync } from '../../../prompts';
|
||||
@@ -11,7 +12,6 @@ import { filterRevokedAndUntrackedPushKeysFromEasServersAsync } from '../appstor
|
||||
import { APPLE_KEYS_TOO_MANY_GENERATED_ERROR } from '../appstore/pushKey';
|
||||
import { pushKeySchema } from '../credentials';
|
||||
import { isPushKeyValidAndTrackedAsync } from '../validators/validatePushKey';
|
||||
import { formatAppleTeam } from './AppleTeamFormatting';
|
||||
|
||||
export async function provideOrGeneratePushKeyAsync(ctx: CredentialsContext): Promise<PushKey> {
|
||||
if (!ctx.nonInteractive) {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { selectAscApiKeysFromAccountAsync } from './AscApiKeyUtils';
|
||||
import { AccountFragment, AppStoreConnectApiKeyFragment } from '../../../graphql/generated';
|
||||
import Log from '../../../log';
|
||||
import { confirmAsync } from '../../../prompts';
|
||||
import { CredentialsContext } from '../../context';
|
||||
import { selectAscApiKeysFromAccountAsync } from './AscApiKeyUtils';
|
||||
|
||||
export class SelectAndRemoveAscApiKey {
|
||||
constructor(private account: AccountFragment) {}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { selectDistributionCertificateWithDependenciesAsync } from './DistributionCertificateUtils';
|
||||
import { RemoveProvisioningProfiles } from './RemoveProvisioningProfile';
|
||||
import {
|
||||
AccountFragment,
|
||||
AppleDistributionCertificateFragment,
|
||||
@@ -7,8 +9,6 @@ import Log from '../../../log';
|
||||
import { confirmAsync } from '../../../prompts';
|
||||
import { CredentialsContext } from '../../context';
|
||||
import { AppLookupParams } from '../api/graphql/types/AppLookupParams';
|
||||
import { selectDistributionCertificateWithDependenciesAsync } from './DistributionCertificateUtils';
|
||||
import { RemoveProvisioningProfiles } from './RemoveProvisioningProfile';
|
||||
|
||||
export class SelectAndRemoveDistributionCertificate {
|
||||
constructor(private account: AccountFragment) {}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { selectPushKeyAsync } from './PushKeyUtils';
|
||||
import { AccountFragment, ApplePushKeyFragment } from '../../../graphql/generated';
|
||||
import Log from '../../../log';
|
||||
import { confirmAsync } from '../../../prompts';
|
||||
import { CredentialsContext } from '../../context';
|
||||
import { selectPushKeyAsync } from './PushKeyUtils';
|
||||
|
||||
export class SelectAndRemovePushKey {
|
||||
constructor(private account: AccountFragment) {}
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
import { ProfileType } from '@expo/apple-utils';
|
||||
import { Errors } from '@oclif/core';
|
||||
import assert from 'assert';
|
||||
import chalk from 'chalk';
|
||||
import nullthrows from 'nullthrows';
|
||||
|
||||
import { resolveAppleTeamIfAuthenticatedAsync } from './AppleTeamUtils';
|
||||
import { assignBuildCredentialsAsync, getBuildCredentialsAsync } from './BuildCredentialsUtils';
|
||||
import { chooseDevicesAsync, formatDeviceLabel } from './DeviceUtils';
|
||||
import { SetUpDistributionCertificate } from './SetUpDistributionCertificate';
|
||||
import DeviceCreateAction, { RegistrationMethod } from '../../../devices/actions/create/action';
|
||||
import {
|
||||
AppleAppIdentifierFragment,
|
||||
@@ -15,7 +20,12 @@ import {
|
||||
} from '../../../graphql/generated';
|
||||
import Log from '../../../log';
|
||||
import { getApplePlatformFromTarget } from '../../../project/ios/target';
|
||||
import { confirmAsync, pressAnyKeyToContinueAsync, promptAsync } from '../../../prompts';
|
||||
import {
|
||||
confirmAsync,
|
||||
pressAnyKeyToContinueAsync,
|
||||
promptAsync,
|
||||
selectAsync,
|
||||
} from '../../../prompts';
|
||||
import differenceBy from '../../../utils/expodash/differenceBy';
|
||||
import { CredentialsContext } from '../../context';
|
||||
import { MissingCredentialsNonInteractiveError } from '../../errors';
|
||||
@@ -24,10 +34,6 @@ import { ProvisioningProfile } from '../appstore/Credentials.types';
|
||||
import { ApplePlatform } from '../appstore/constants';
|
||||
import { Target } from '../types';
|
||||
import { validateProvisioningProfileAsync } from '../validators/validateProvisioningProfile';
|
||||
import { resolveAppleTeamIfAuthenticatedAsync } from './AppleTeamUtils';
|
||||
import { assignBuildCredentialsAsync, getBuildCredentialsAsync } from './BuildCredentialsUtils';
|
||||
import { chooseDevicesAsync, formatDeviceLabel } from './DeviceUtils';
|
||||
import { SetUpDistributionCertificate } from './SetUpDistributionCertificate';
|
||||
|
||||
enum ReuseAction {
|
||||
Yes,
|
||||
@@ -181,6 +187,22 @@ export class SetUpAdhocProvisioningProfile {
|
||||
Log.log(
|
||||
'Most commonly devices fail to to be provisioned while they are still being processed by Apple, which can take up to 24-72 hours. Check your Apple Developer Portal page at https://developer.apple.com/account/resources/devices/list, the devices in "Processing" status cannot be provisioned yet'
|
||||
);
|
||||
const shouldContinue = await selectAsync(
|
||||
'Do you want to continue without provisioning these devices?',
|
||||
[
|
||||
{
|
||||
title: 'Yes',
|
||||
value: true,
|
||||
},
|
||||
{
|
||||
title: 'No (EAS CLI will exit)',
|
||||
value: false,
|
||||
},
|
||||
]
|
||||
);
|
||||
if (!shouldContinue) {
|
||||
Errors.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// 7. Create (or update) app build credentials
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
import assert from 'assert';
|
||||
import nullthrows from 'nullthrows';
|
||||
|
||||
import {
|
||||
AppStoreApiKeyPurpose,
|
||||
formatAscApiKey,
|
||||
getAscApiKeysFromAccountAsync,
|
||||
selectAscApiKeysFromAccountAsync,
|
||||
sortAscApiKeysByUpdatedAtDesc,
|
||||
} from './AscApiKeyUtils';
|
||||
import { AssignAscApiKey } from './AssignAscApiKey';
|
||||
import { CreateAscApiKey } from './CreateAscApiKey';
|
||||
import {
|
||||
AppStoreConnectApiKeyFragment,
|
||||
CommonIosAppCredentialsFragment,
|
||||
@@ -14,15 +23,6 @@ import {
|
||||
} from '../../errors';
|
||||
import { AppLookupParams } from '../api/graphql/types/AppLookupParams';
|
||||
import { getValidAndTrackedAscApiKeysAsync } from '../validators/validateAscApiKey';
|
||||
import {
|
||||
AppStoreApiKeyPurpose,
|
||||
formatAscApiKey,
|
||||
getAscApiKeysFromAccountAsync,
|
||||
selectAscApiKeysFromAccountAsync,
|
||||
sortAscApiKeysByUpdatedAtDesc,
|
||||
} from './AscApiKeyUtils';
|
||||
import { AssignAscApiKey } from './AssignAscApiKey';
|
||||
import { CreateAscApiKey } from './CreateAscApiKey';
|
||||
|
||||
export enum SetupAscApiKeyChoice {
|
||||
GENERATE = 'GENERATE',
|
||||
@@ -37,7 +37,10 @@ export class SetUpAscApiKey {
|
||||
{ title: '[Add a new key]', value: SetupAscApiKeyChoice.GENERATE },
|
||||
];
|
||||
|
||||
constructor(private app: AppLookupParams, private purpose: AppStoreApiKeyPurpose) {}
|
||||
constructor(
|
||||
private app: AppLookupParams,
|
||||
private purpose: AppStoreApiKeyPurpose
|
||||
) {}
|
||||
|
||||
public async runAsync(ctx: CredentialsContext): Promise<CommonIosAppCredentialsFragment> {
|
||||
const isKeySetup = await this.isAscApiKeySetupAsync(ctx, this.purpose);
|
||||
|
||||
@@ -2,11 +2,11 @@ import { DistributionType, IosEnterpriseProvisioning } from '@expo/eas-json';
|
||||
import chalk from 'chalk';
|
||||
import nullthrows from 'nullthrows';
|
||||
|
||||
import { SetUpTargetBuildCredentials } from './SetUpTargetBuildCredentials';
|
||||
import Log from '../../../log';
|
||||
import { CredentialsContext } from '../../context';
|
||||
import { App, IosAppBuildCredentialsMap, IosCredentials, Target } from '../types';
|
||||
import { displayProjectCredentials } from '../utils/printCredentials';
|
||||
import { SetUpTargetBuildCredentials } from './SetUpTargetBuildCredentials';
|
||||
|
||||
interface Options {
|
||||
app: App;
|
||||
|
||||
+1
-1
@@ -1,5 +1,6 @@
|
||||
import chalk from 'chalk';
|
||||
|
||||
import { SetUpTargetBuildCredentialsFromCredentialsJson } from './SetUpTargetBuildCredentialsFromCredentialsJson';
|
||||
import { IosDistributionType } from '../../../graphql/generated';
|
||||
import Log from '../../../log';
|
||||
import { findApplicationTarget } from '../../../project/ios/target';
|
||||
@@ -8,7 +9,6 @@ import { readIosCredentialsAsync } from '../../credentialsJson/read';
|
||||
import { IosCredentials } from '../../credentialsJson/types';
|
||||
import { ensureAllTargetsAreConfigured } from '../../credentialsJson/utils';
|
||||
import { App, Target } from '../types';
|
||||
import { SetUpTargetBuildCredentialsFromCredentialsJson } from './SetUpTargetBuildCredentialsFromCredentialsJson';
|
||||
|
||||
export class SetUpBuildCredentialsFromCredentialsJson {
|
||||
constructor(
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import assert from 'assert';
|
||||
|
||||
import { resolveAppleTeamIfAuthenticatedAsync } from './AppleTeamUtils';
|
||||
import { CreateDistributionCertificate } from './CreateDistributionCertificate';
|
||||
import { formatDistributionCertificate } from './DistributionCertificateUtils';
|
||||
import {
|
||||
AppleDistributionCertificate,
|
||||
AppleDistributionCertificateFragment,
|
||||
@@ -14,14 +17,14 @@ import { AppleDistributionCertificateMutationResult } from '../api/graphql/mutat
|
||||
import { AppLookupParams } from '../api/graphql/types/AppLookupParams';
|
||||
import { getValidCertSerialNumbers } from '../appstore/CredentialsUtils';
|
||||
import { AppleTeamMissingError } from '../errors';
|
||||
import { resolveAppleTeamIfAuthenticatedAsync } from './AppleTeamUtils';
|
||||
import { CreateDistributionCertificate } from './CreateDistributionCertificate';
|
||||
import { formatDistributionCertificate } from './DistributionCertificateUtils';
|
||||
|
||||
export class SetUpDistributionCertificate {
|
||||
private validDistCerts?: AppleDistributionCertificateFragment[];
|
||||
|
||||
constructor(private app: AppLookupParams, private distributionType: IosDistributionType) {}
|
||||
constructor(
|
||||
private app: AppLookupParams,
|
||||
private distributionType: IosDistributionType
|
||||
) {}
|
||||
|
||||
public async runAsync(ctx: CredentialsContext): Promise<AppleDistributionCertificateFragment> {
|
||||
const appleTeam = await resolveAppleTeamIfAuthenticatedAsync(ctx, this.app);
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { getAllBuildCredentialsAsync } from './BuildCredentialsUtils';
|
||||
import { SetUpAdhocProvisioningProfile } from './SetUpAdhocProvisioningProfile';
|
||||
import { SetUpProvisioningProfile } from './SetUpProvisioningProfile';
|
||||
import { IosAppBuildCredentialsFragment, IosDistributionType } from '../../../graphql/generated';
|
||||
import Log, { learnMore } from '../../../log';
|
||||
import { promptAsync } from '../../../prompts';
|
||||
import { CredentialsContext } from '../../context';
|
||||
import { AppLookupParams } from '../api/graphql/types/AppLookupParams';
|
||||
import { Target } from '../types';
|
||||
import { getAllBuildCredentialsAsync } from './BuildCredentialsUtils';
|
||||
import { SetUpAdhocProvisioningProfile } from './SetUpAdhocProvisioningProfile';
|
||||
import { SetUpProvisioningProfile } from './SetUpProvisioningProfile';
|
||||
|
||||
/**
|
||||
* It's used when setting up credentials for internal distribution but `enterpriseProvisioning` is not set.
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
import nullthrows from 'nullthrows';
|
||||
|
||||
import {
|
||||
assignBuildCredentialsAsync,
|
||||
getBuildCredentialsAsync,
|
||||
getProvisioningProfileAsync,
|
||||
} from './BuildCredentialsUtils';
|
||||
import { ConfigureProvisioningProfile } from './ConfigureProvisioningProfile';
|
||||
import { CreateProvisioningProfile } from './CreateProvisioningProfile';
|
||||
import { formatProvisioningProfileFromApple } from './ProvisioningProfileUtils';
|
||||
import { SetUpDistributionCertificate } from './SetUpDistributionCertificate';
|
||||
import {
|
||||
AppleDistributionCertificateFragment,
|
||||
AppleProvisioningProfileFragment,
|
||||
@@ -14,15 +23,6 @@ import { AppLookupParams } from '../api/graphql/types/AppLookupParams';
|
||||
import { ProvisioningProfileStoreInfo } from '../appstore/Credentials.types';
|
||||
import { Target } from '../types';
|
||||
import { validateProvisioningProfileAsync } from '../validators/validateProvisioningProfile';
|
||||
import {
|
||||
assignBuildCredentialsAsync,
|
||||
getBuildCredentialsAsync,
|
||||
getProvisioningProfileAsync,
|
||||
} from './BuildCredentialsUtils';
|
||||
import { ConfigureProvisioningProfile } from './ConfigureProvisioningProfile';
|
||||
import { CreateProvisioningProfile } from './CreateProvisioningProfile';
|
||||
import { formatProvisioningProfileFromApple } from './ProvisioningProfileUtils';
|
||||
import { SetUpDistributionCertificate } from './SetUpDistributionCertificate';
|
||||
|
||||
/**
|
||||
* Sets up either APP_STORE or ENTERPRISE provisioning profiles
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
import assert from 'assert';
|
||||
import nullthrows from 'nullthrows';
|
||||
|
||||
import { ApplePushKeyFragment, CommonIosAppCredentialsFragment } from '../../../graphql/generated';
|
||||
import Log from '../../../log';
|
||||
import { confirmAsync, promptAsync } from '../../../prompts';
|
||||
import { CredentialsContext } from '../../context';
|
||||
import { AppLookupParams } from '../api/graphql/types/AppLookupParams';
|
||||
import { AssignPushKey } from './AssignPushKey';
|
||||
import { CreatePushKey } from './CreatePushKey';
|
||||
import {
|
||||
@@ -13,6 +8,11 @@ import {
|
||||
getValidAndTrackedPushKeysOnEasServersAsync,
|
||||
selectPushKeyAsync,
|
||||
} from './PushKeyUtils';
|
||||
import { ApplePushKeyFragment, CommonIosAppCredentialsFragment } from '../../../graphql/generated';
|
||||
import Log from '../../../log';
|
||||
import { confirmAsync, promptAsync } from '../../../prompts';
|
||||
import { CredentialsContext } from '../../context';
|
||||
import { AppLookupParams } from '../api/graphql/types/AppLookupParams';
|
||||
|
||||
export class SetUpPushKey {
|
||||
constructor(private app: AppLookupParams) {}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { DistributionType, IosEnterpriseProvisioning } from '@expo/eas-json';
|
||||
import { JSONObject } from '@expo/json-file';
|
||||
|
||||
import { SetUpAdhocProvisioningProfile } from './SetUpAdhocProvisioningProfile';
|
||||
import { SetUpInternalProvisioningProfile } from './SetUpInternalProvisioningProfile';
|
||||
import { SetUpProvisioningProfile } from './SetUpProvisioningProfile';
|
||||
import {
|
||||
IosDistributionType as GraphQLIosDistributionType,
|
||||
IosAppBuildCredentialsFragment,
|
||||
@@ -9,9 +12,6 @@ import Log from '../../../log';
|
||||
import { CredentialsContext } from '../../context';
|
||||
import { AppLookupParams as GraphQLAppLookupParams } from '../api/graphql/types/AppLookupParams';
|
||||
import { Target } from '../types';
|
||||
import { SetUpAdhocProvisioningProfile } from './SetUpAdhocProvisioningProfile';
|
||||
import { SetUpInternalProvisioningProfile } from './SetUpInternalProvisioningProfile';
|
||||
import { SetUpProvisioningProfile } from './SetUpProvisioningProfile';
|
||||
|
||||
interface Options {
|
||||
app: GraphQLAppLookupParams;
|
||||
|
||||
+6
-6
@@ -1,6 +1,12 @@
|
||||
import chalk from 'chalk';
|
||||
import nullthrows from 'nullthrows';
|
||||
|
||||
import {
|
||||
assignBuildCredentialsAsync,
|
||||
getBuildCredentialsAsync,
|
||||
getDistributionCertificateAsync,
|
||||
getProvisioningProfileAsync,
|
||||
} from './BuildCredentialsUtils';
|
||||
import {
|
||||
AppleDistributionCertificateFragment,
|
||||
AppleProvisioningProfileFragment,
|
||||
@@ -15,12 +21,6 @@ import { IosTargetCredentials } from '../../credentialsJson/types';
|
||||
import { AppLookupParams } from '../api/graphql/types/AppLookupParams';
|
||||
import { displayProjectCredentials } from '../utils/printCredentials';
|
||||
import { readAppleTeam } from '../utils/provisioningProfile';
|
||||
import {
|
||||
assignBuildCredentialsAsync,
|
||||
getBuildCredentialsAsync,
|
||||
getDistributionCertificateAsync,
|
||||
getProvisioningProfileAsync,
|
||||
} from './BuildCredentialsUtils';
|
||||
|
||||
export class SetUpTargetBuildCredentialsFromCredentialsJson {
|
||||
constructor(
|
||||
|
||||
+3
@@ -14,6 +14,7 @@ import {
|
||||
} from '../../../../graphql/generated';
|
||||
import Log from '../../../../log';
|
||||
import { getApplePlatformFromTarget } from '../../../../project/ios/target';
|
||||
import { selectAsync } from '../../../../prompts';
|
||||
import { Actor } from '../../../../user/User';
|
||||
import { Client } from '../../../../vcs/vcs';
|
||||
import { CredentialsContext, CredentialsContextProjectInfo } from '../../../context';
|
||||
@@ -34,6 +35,7 @@ jest.mock('../DeviceUtils', () => {
|
||||
};
|
||||
});
|
||||
jest.mock('../../../../project/ios/target');
|
||||
jest.mock('../../../../prompts');
|
||||
|
||||
describe(doUDIDsMatch, () => {
|
||||
it('return false if UDIDs do not match', () => {
|
||||
@@ -67,6 +69,7 @@ describe('runWithDistributionCertificateAsync', () => {
|
||||
developerPortalIdentifier: 'provisioningProfileId',
|
||||
},
|
||||
} as IosAppBuildCredentialsFragment);
|
||||
jest.mocked(selectAsync).mockImplementation(async () => true);
|
||||
ctx.ios.updateProvisioningProfileAsync = jest.fn().mockResolvedValue({
|
||||
appleTeam: {},
|
||||
appleDevices: [{ identifier: 'id1' }],
|
||||
|
||||
@@ -1,26 +1,6 @@
|
||||
import { UserRole } from '@expo/apple-utils';
|
||||
import nullthrows from 'nullthrows';
|
||||
|
||||
import { ExpoGraphqlClient } from '../../../commandUtils/context/contextUtils/createGraphqlClient';
|
||||
import {
|
||||
AccountFragment,
|
||||
AppFragment,
|
||||
AppStoreConnectApiKeyFragment,
|
||||
AppStoreConnectUserRole,
|
||||
AppleAppIdentifierFragment,
|
||||
AppleDeviceFragment,
|
||||
AppleDistributionCertificateFragment,
|
||||
ApplePushKeyFragment,
|
||||
AppleTeamFragment,
|
||||
CommonIosAppCredentialsFragment,
|
||||
IosAppBuildCredentialsFragment,
|
||||
IosDistributionType,
|
||||
} from '../../../graphql/generated';
|
||||
import { AppQuery } from '../../../graphql/queries/AppQuery';
|
||||
import { isWildcardBundleIdentifier } from '../../../project/ios/bundleIdentifier';
|
||||
import { DistributionCertificate, PushKey } from '../appstore/Credentials.types';
|
||||
import { MinimalAscApiKey } from '../credentials';
|
||||
import { AppleTeamMissingError } from '../errors';
|
||||
import { AppStoreConnectApiKeyMutation } from './graphql/mutations/AppStoreConnectApiKeyMutation';
|
||||
import { AppleAppIdentifierMutation } from './graphql/mutations/AppleAppIdentifierMutation';
|
||||
import {
|
||||
@@ -47,6 +27,26 @@ import { ApplePushKeyQuery } from './graphql/queries/ApplePushKeyQuery';
|
||||
import { AppleTeamQuery } from './graphql/queries/AppleTeamQuery';
|
||||
import { IosAppCredentialsQuery } from './graphql/queries/IosAppCredentialsQuery';
|
||||
import { AppLookupParams } from './graphql/types/AppLookupParams';
|
||||
import { ExpoGraphqlClient } from '../../../commandUtils/context/contextUtils/createGraphqlClient';
|
||||
import {
|
||||
AccountFragment,
|
||||
AppFragment,
|
||||
AppStoreConnectApiKeyFragment,
|
||||
AppStoreConnectUserRole,
|
||||
AppleAppIdentifierFragment,
|
||||
AppleDeviceFragment,
|
||||
AppleDistributionCertificateFragment,
|
||||
ApplePushKeyFragment,
|
||||
AppleTeamFragment,
|
||||
CommonIosAppCredentialsFragment,
|
||||
IosAppBuildCredentialsFragment,
|
||||
IosDistributionType,
|
||||
} from '../../../graphql/generated';
|
||||
import { AppQuery } from '../../../graphql/queries/AppQuery';
|
||||
import { isWildcardBundleIdentifier } from '../../../project/ios/bundleIdentifier';
|
||||
import { DistributionCertificate, PushKey } from '../appstore/Credentials.types';
|
||||
import { MinimalAscApiKey } from '../credentials';
|
||||
import { AppleTeamMissingError } from '../errors';
|
||||
|
||||
async function getAppAsync(
|
||||
graphqlClient: ExpoGraphqlClient,
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import { ProfileType } from '@expo/app-store';
|
||||
|
||||
import { Analytics } from '../../../analytics/AnalyticsManager';
|
||||
import Log from '../../../log';
|
||||
import {
|
||||
AscApiKey,
|
||||
AscApiKeyInfo,
|
||||
@@ -46,6 +44,8 @@ import {
|
||||
import { createOrReuseAdhocProvisioningProfileAsync } from './provisioningProfileAdhoc';
|
||||
import { createPushKeyAsync, listPushKeysAsync, revokePushKeyAsync } from './pushKey';
|
||||
import { hasAscEnvVars } from './resolveCredentials';
|
||||
import { Analytics } from '../../../analytics/AnalyticsManager';
|
||||
import Log from '../../../log';
|
||||
|
||||
export default class AppStoreApi {
|
||||
public authCtx?: AuthCtx;
|
||||
|
||||
Loaded 100 of 193 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user