eas-cli 18.12.1 → 18.12.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,6 +5,7 @@ export default class Go extends EasCommand {
5
5
  static flags: {
6
6
  'bundle-id': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
7
7
  name: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
8
+ 'sdk-version': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
8
9
  credentials: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
9
10
  };
10
11
  static contextDefinition: {
@@ -13,11 +14,9 @@ export default class Go extends EasCommand {
13
14
  };
14
15
  runAsync(): Promise<void>;
15
16
  private generateBundleId;
16
- private createProjectFilesAsync;
17
- private initGitRepoAsync;
18
17
  private ensureEasProjectAsync;
19
18
  private setupCredentialsAsync;
20
- private runWorkflowAsync;
19
+ private dispatchWorkflowAsync;
21
20
  private monitorWorkflowJobsAsync;
22
21
  private formatSpinnerText;
23
22
  }
@@ -2,14 +2,12 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const apple_utils_1 = require("@expo/apple-utils");
5
- const spawn_async_1 = tslib_1.__importDefault(require("@expo/spawn-async"));
6
5
  const core_1 = require("@oclif/core");
7
6
  const chalk_1 = tslib_1.__importDefault(require("chalk"));
8
7
  const fs = tslib_1.__importStar(require("fs-extra"));
9
8
  const os = tslib_1.__importStar(require("os"));
10
9
  const path = tslib_1.__importStar(require("path"));
11
10
  const EasCommand_1 = tslib_1.__importDefault(require("../commandUtils/EasCommand"));
12
- const getProjectIdAsync_1 = require("../commandUtils/context/contextUtils/getProjectIdAsync");
13
11
  const context_1 = require("../credentials/context");
14
12
  const AscApiKeyUtils_1 = require("../credentials/ios/actions/AscApiKeyUtils");
15
13
  const BuildCredentialsUtils_1 = require("../credentials/ios/actions/BuildCredentialsUtils");
@@ -18,27 +16,26 @@ const SetUpBuildCredentials_1 = require("../credentials/ios/actions/SetUpBuildCr
18
16
  const SetUpPushKey_1 = require("../credentials/ios/actions/SetUpPushKey");
19
17
  const ensureAppExists_1 = require("../credentials/ios/appstore/ensureAppExists");
20
18
  const generated_1 = require("../graphql/generated");
19
+ const url_1 = require("../build/utils/url");
21
20
  const AppMutation_1 = require("../graphql/mutations/AppMutation");
22
21
  const WorkflowRunMutation_1 = require("../graphql/mutations/WorkflowRunMutation");
23
- const AppQuery_1 = require("../graphql/queries/AppQuery");
24
22
  const WorkflowRunQuery_1 = require("../graphql/queries/WorkflowRunQuery");
25
23
  const log_1 = tslib_1.__importStar(require("../log"));
26
24
  const prompts_1 = require("../prompts");
27
25
  const ora_1 = require("../ora");
28
- const expoConfig_1 = require("../project/expoConfig");
29
26
  const fetchOrCreateProjectIDForWriteToConfigWithConfirmationAsync_1 = require("../project/fetchOrCreateProjectIDForWriteToConfigWithConfirmationAsync");
30
27
  const uploadAccountScopedFileAsync_1 = require("../project/uploadAccountScopedFileAsync");
31
28
  const uploadAccountScopedProjectSourceAsync_1 = require("../project/uploadAccountScopedProjectSourceAsync");
29
+ const actions_1 = require("../user/actions");
32
30
  const User_1 = require("../user/User");
33
31
  const promise_1 = require("../utils/promise");
34
- const vcs_1 = require("../vcs");
35
- // Expo Go release info - update when releasing a new version
36
- const EXPO_GO_SDK_VERSION = '55';
37
- const EXPO_GO_APP_VERSION = '55.0.11';
38
- const EXPO_GO_BUILD_NUMBER = '1017799';
32
+ const noVcs_1 = tslib_1.__importDefault(require("../vcs/clients/noVcs"));
33
+ const bundleIdentifier_1 = require("../project/ios/bundleIdentifier");
34
+ function deriveBundleIdSlug(bundleId) {
35
+ return bundleId.split('.').filter(Boolean).pop();
36
+ }
39
37
  const TESTFLIGHT_GROUP_NAME = 'Team (Expo)';
40
38
  async function setupTestFlightAsync(ascApp) {
41
- // Create or get TestFlight group
42
39
  let group;
43
40
  for (let attempt = 0; attempt < 10; attempt++) {
44
41
  try {
@@ -59,7 +56,7 @@ async function setupTestFlightAsync(ascApp) {
59
56
  // Apple returns this error when the app isn't ready yet
60
57
  if (error?.data?.errors?.some((e) => e.code === 'ENTITY_ERROR.RELATIONSHIP.INVALID')) {
61
58
  if (attempt < 9) {
62
- await new Promise(resolve => setTimeout(resolve, 10000));
59
+ await (0, promise_1.sleepAsync)(10_000);
63
60
  continue;
64
61
  }
65
62
  }
@@ -96,23 +93,18 @@ async function withSuppressedOutputAsync(fn) {
96
93
  }
97
94
  return true;
98
95
  };
99
- // Only suppress stdout, not stderr ora writes spinner frames to stderr and
100
- // patching it would freeze the spinner animation during suppressed async work.
96
+ // Suppress stdout and console output during credential setup so its verbose
97
+ // log lines don't interleave with our progress spinners.
101
98
  process.stdout.write = capture;
102
99
  console.log = () => { };
103
100
  console.error = () => { };
104
101
  console.warn = () => { };
102
+ let didThrow = false;
105
103
  try {
106
104
  return await fn();
107
105
  }
108
106
  catch (error) {
109
- process.stdout.write = originalStdoutWrite;
110
- console.log = originalConsoleLog;
111
- console.error = originalConsoleError;
112
- console.warn = originalConsoleWarn;
113
- if (capturedOutput) {
114
- originalConsoleLog(capturedOutput);
115
- }
107
+ didThrow = true;
116
108
  throw error;
117
109
  }
118
110
  finally {
@@ -120,6 +112,9 @@ async function withSuppressedOutputAsync(fn) {
120
112
  console.log = originalConsoleLog;
121
113
  console.error = originalConsoleError;
122
114
  console.warn = originalConsoleWarn;
115
+ if (didThrow && capturedOutput) {
116
+ originalConsoleLog(capturedOutput);
117
+ }
123
118
  }
124
119
  }
125
120
  /* eslint-enable no-console */
@@ -135,6 +130,10 @@ class Go extends EasCommand_1.default {
135
130
  description: 'App name',
136
131
  default: 'My Expo Go',
137
132
  }),
133
+ 'sdk-version': core_1.Flags.string({
134
+ description: 'Expo Go SDK version to prepare (default: latest)',
135
+ required: false,
136
+ }),
138
137
  credentials: core_1.Flags.boolean({
139
138
  description: 'Interactively select credentials (default: auto-select)',
140
139
  default: false,
@@ -151,157 +150,81 @@ class Go extends EasCommand_1.default {
151
150
  nonInteractive: false,
152
151
  });
153
152
  log_1.default.withTick(`Logged in as ${chalk_1.default.cyan((0, User_1.getActorDisplayName)(actor))}`);
153
+ const sdkVersion = flags['sdk-version'];
154
154
  const bundleId = flags['bundle-id'] ?? this.generateBundleId(actor);
155
- const appName = flags.name ?? 'My Expo Go';
156
- const slug = bundleId.split('.').pop() || 'my-expo-go';
157
- const projectDir = path.join(os.tmpdir(), `eas-go-${slug}`);
158
- await fs.emptyDir(projectDir);
159
- const originalCwd = process.cwd();
160
- process.chdir(projectDir);
161
- const setupSpinner = (0, ora_1.ora)('Creating project...').start();
162
- // Step 1: Create project files and initialize git (silently)
155
+ if (!(0, bundleIdentifier_1.isBundleIdentifierValid)(bundleId)) {
156
+ throw new Error(`"${bundleId}" is not a valid iOS bundle identifier. ${bundleIdentifier_1.INVALID_BUNDLE_IDENTIFIER_MESSAGE} Pass a valid identifier with --bundle-id.`);
157
+ }
158
+ const appName = flags.name;
159
+ const slug = deriveBundleIdSlug(bundleId);
160
+ const setupSpinner = (0, ora_1.ora)('Setting up project...').start();
161
+ let projectId;
163
162
  try {
164
- await withSuppressedOutputAsync(async () => {
165
- await this.createProjectFilesAsync(projectDir, bundleId, appName);
166
- await this.initGitRepoAsync(projectDir);
167
- });
168
- const vcsClient = (0, vcs_1.resolveVcsClient)();
169
- // Step 2: Create/link EAS project (silently)
170
- const projectId = await withSuppressedOutputAsync(() => this.ensureEasProjectAsync(graphqlClient, actor, projectDir, bundleId));
171
- // Step 3: Set up iOS credentials and create App Store Connect app
172
- const ascApp = await this.setupCredentialsAsync(projectDir, projectId, bundleId, appName, graphqlClient, actor, analytics, vcsClient, flags.credentials, () => {
163
+ projectId = await withSuppressedOutputAsync(() => this.ensureEasProjectAsync(graphqlClient, actor, slug));
164
+ }
165
+ catch (error) {
166
+ setupSpinner.fail();
167
+ throw error;
168
+ }
169
+ const tmpDir = path.join(os.tmpdir(), `eas-go-${Date.now()}`);
170
+ await fs.ensureDir(tmpDir);
171
+ const vcsClient = new noVcs_1.default({ cwdOverride: tmpDir });
172
+ try {
173
+ const ascApp = await this.setupCredentialsAsync(slug, projectId, bundleId, appName, graphqlClient, actor, analytics, vcsClient, flags.credentials, () => {
173
174
  setupSpinner.stop();
174
175
  log_1.default.markFreshLine();
175
176
  });
176
- // Step 4: Start workflow and monitor progress
177
- const { workflowUrl, workflowRunId } = await this.runWorkflowAsync(graphqlClient, projectDir, projectId, actor, vcsClient);
178
- log_1.default.withTick(`Workflow started: ${chalk_1.default.cyan(workflowUrl)}`);
177
+ const { workflowUrl, workflowRunId } = await this.dispatchWorkflowAsync(graphqlClient, projectId, actor, bundleId, appName, ascApp.id, sdkVersion, tmpDir, vcsClient);
178
+ log_1.default.withTick(`Build started: ${chalk_1.default.cyan(workflowUrl)}`);
179
179
  const status = await this.monitorWorkflowJobsAsync(graphqlClient, workflowRunId);
180
180
  if (status === generated_1.WorkflowRunStatus.Failure) {
181
- throw new Error('Workflow failed');
181
+ throw new Error('Build failed');
182
182
  }
183
183
  else if (status === generated_1.WorkflowRunStatus.Canceled) {
184
- throw new Error('Workflow was canceled');
184
+ throw new Error('Build was canceled');
185
185
  }
186
- // Step 5: Set up TestFlight group (silently)
187
186
  try {
188
187
  await setupTestFlightAsync(ascApp);
189
188
  }
190
- catch {
191
- // Non-fatal: TestFlight group setup failure shouldn't block the user
189
+ catch (e) {
190
+ log_1.default.debug('TestFlight group setup failed:', e);
192
191
  }
193
192
  log_1.default.newLine();
194
193
  log_1.default.succeed(`Done! Your custom Expo Go has been submitted to TestFlight. ${(0, log_1.learnMore)(`https://appstoreconnect.apple.com/apps/${ascApp.id}/testflight`, { learnMoreMessage: 'Open it on App Store Connect' })}`);
195
194
  log_1.default.log(`App Store processing may take several minutes to complete. ${(0, log_1.learnMore)('https://expo.fyi/personal-expo-go', { learnMoreMessage: 'Learn more about Expo Go on TestFlight' })}`);
196
- await fs.remove(projectDir);
197
- }
198
- catch (error) {
199
- log_1.default.gray(`Project files preserved for debugging: ${projectDir}`);
200
- throw error;
201
195
  }
202
196
  finally {
203
- process.chdir(originalCwd);
197
+ await fs.remove(tmpDir);
204
198
  }
205
199
  }
206
200
  generateBundleId(actor) {
207
- const username = actor.accounts[0].name;
208
- // Sanitize username for bundle ID: only alphanumeric and hyphens allowed
201
+ const username = (0, actions_1.ensureActorHasPrimaryAccount)(actor).name;
209
202
  const sanitizedUsername = username
210
203
  .toLowerCase()
211
- .replace(/[^a-z0-9-]/g, '')
212
- .replace(/^-+|-+$/g, ''); // trim leading/trailing hyphens
213
- // Deterministic bundle ID per user + SDK version (reuses same ASC app)
214
- return `com.${sanitizedUsername || 'app'}.expogo${EXPO_GO_SDK_VERSION}`;
204
+ .replace(/[^a-z0-9-]/g, '-')
205
+ .replace(/-{2,}/g, '-')
206
+ .replace(/^-+|-+$/g, '');
207
+ return `com.${sanitizedUsername}.expogo`;
215
208
  }
216
- async createProjectFilesAsync(projectDir, bundleId, appName) {
217
- const slug = bundleId.split('.').pop() || 'custom-expo-go';
218
- const extensionBundleId = `${bundleId}.ExpoNotificationServiceExtension`;
219
- const appJson = {
220
- expo: {
221
- name: appName,
222
- slug,
223
- version: EXPO_GO_APP_VERSION,
224
- ios: {
225
- bundleIdentifier: bundleId,
226
- buildNumber: EXPO_GO_BUILD_NUMBER,
227
- config: {
228
- usesNonExemptEncryption: false,
229
- },
230
- },
231
- extra: {
232
- eas: {
233
- build: {
234
- experimental: {
235
- ios: {
236
- appExtensions: [
237
- {
238
- targetName: 'ExpoNotificationServiceExtension',
239
- bundleIdentifier: extensionBundleId,
240
- },
241
- ],
242
- },
243
- },
244
- },
245
- },
246
- },
247
- },
248
- };
249
- const easJson = {
250
- cli: {
251
- version: '>= 5.0.0',
252
- },
253
- build: {
254
- production: {
255
- distribution: 'store',
256
- credentialsSource: 'remote',
257
- },
258
- },
259
- submit: {
260
- production: {
261
- ios: {},
262
- },
263
- },
264
- };
265
- const packageJson = {
266
- name: slug,
267
- version: '1.0.0',
268
- dependencies: {
269
- expo: '~54.0.0',
270
- },
271
- };
272
- await fs.writeJson(path.join(projectDir, 'app.json'), appJson, { spaces: 2 });
273
- await fs.writeJson(path.join(projectDir, 'eas.json'), easJson, { spaces: 2 });
274
- await fs.writeJson(path.join(projectDir, 'package.json'), packageJson, { spaces: 2 });
275
- await (0, spawn_async_1.default)('npm', ['install'], { cwd: projectDir });
276
- }
277
- async initGitRepoAsync(projectDir) {
278
- await (0, spawn_async_1.default)('git', ['init'], { cwd: projectDir });
279
- await (0, spawn_async_1.default)('git', ['add', '.'], { cwd: projectDir });
280
- await (0, spawn_async_1.default)('git', ['commit', '-m', 'Initial commit'], { cwd: projectDir });
281
- }
282
- async ensureEasProjectAsync(graphqlClient, actor, projectDir, bundleId) {
283
- const slug = bundleId.split('.').pop() || 'custom-expo-go';
284
- const account = actor.accounts[0];
209
+ async ensureEasProjectAsync(graphqlClient, actor, slug) {
210
+ const account = (0, actions_1.ensureActorHasPrimaryAccount)(actor);
285
211
  const existingProjectId = await (0, fetchOrCreateProjectIDForWriteToConfigWithConfirmationAsync_1.findProjectIdByAccountNameAndSlugNullableAsync)(graphqlClient, account.name, slug);
286
212
  if (existingProjectId) {
287
- await (0, getProjectIdAsync_1.saveProjectIdToAppConfigAsync)(projectDir, existingProjectId);
288
213
  return existingProjectId;
289
214
  }
290
- const projectId = await AppMutation_1.AppMutation.createAppAsync(graphqlClient, {
215
+ return await AppMutation_1.AppMutation.createAppAsync(graphqlClient, {
291
216
  accountId: account.id,
292
217
  projectName: slug,
293
218
  });
294
- await (0, getProjectIdAsync_1.saveProjectIdToAppConfigAsync)(projectDir, projectId);
295
- return projectId;
296
219
  }
297
- async setupCredentialsAsync(projectDir, projectId, bundleId, appName, graphqlClient, actor, analytics, vcsClient, customizeCreds, onBeforeAppleAuth) {
298
- const exp = await (0, expoConfig_1.getPrivateExpoConfigAsync)(projectDir);
220
+ async setupCredentialsAsync(slug, projectId, bundleId, appName, graphqlClient, actor, analytics, vcsClient, customizeCreds, onBeforeAppleAuth) {
299
221
  const extensionBundleId = `${bundleId}.ExpoNotificationServiceExtension`;
222
+ const exp = { name: appName, slug, ios: { bundleIdentifier: bundleId } };
300
223
  const credentialsCtx = new context_1.CredentialsContext({
301
224
  projectInfo: { exp, projectId },
302
225
  nonInteractive: false,
303
226
  autoAcceptCredentialReuse: !customizeCreds,
304
- projectDir,
227
+ projectDir: process.cwd(),
305
228
  user: actor,
306
229
  graphqlClient,
307
230
  analytics,
@@ -312,7 +235,7 @@ class Go extends EasCommand_1.default {
312
235
  const app = await (0, BuildCredentialsUtils_1.getAppFromContextAsync)(credentialsCtx);
313
236
  const targets = [
314
237
  {
315
- targetName: exp.slug,
238
+ targetName: slug,
316
239
  bundleIdentifier: bundleId,
317
240
  entitlements: {},
318
241
  },
@@ -323,35 +246,21 @@ class Go extends EasCommand_1.default {
323
246
  entitlements: {},
324
247
  },
325
248
  ];
326
- const ascApp = await withSuppressedOutputAsync(async () => {
327
- await new SetUpBuildCredentials_1.SetUpBuildCredentials({
328
- app,
329
- targets,
330
- distribution: 'store',
331
- }).runAsync(credentialsCtx);
332
- const appLookupParams = {
333
- ...app,
334
- bundleIdentifier: bundleId,
335
- };
336
- await new SetUpAscApiKey_1.SetUpAscApiKey(appLookupParams, AscApiKeyUtils_1.AppStoreApiKeyPurpose.SUBMISSION_SERVICE).runAsync(credentialsCtx);
337
- const ascAppResult = await (0, ensureAppExists_1.ensureAppExistsAsync)(userAuthCtx, {
338
- name: appName,
339
- bundleIdentifier: bundleId,
340
- });
341
- const easJsonPath = path.join(projectDir, 'eas.json');
342
- const easJson = await fs.readJson(easJsonPath);
343
- easJson.submit = easJson.submit || {};
344
- easJson.submit.production = easJson.submit.production || {};
345
- easJson.submit.production.ios = easJson.submit.production.ios || {};
346
- easJson.submit.production.ios.ascAppId = ascAppResult.id;
347
- await fs.writeJson(easJsonPath, easJson, { spaces: 2 });
348
- await (0, spawn_async_1.default)('git', ['add', 'eas.json'], { cwd: projectDir });
349
- await (0, spawn_async_1.default)('git', ['commit', '-m', 'Add ascAppId to eas.json'], { cwd: projectDir });
350
- return ascAppResult;
249
+ await new SetUpBuildCredentials_1.SetUpBuildCredentials({
250
+ app,
251
+ targets,
252
+ distribution: 'store',
253
+ }).runAsync(credentialsCtx);
254
+ const appLookupParams = {
255
+ ...app,
256
+ bundleIdentifier: bundleId,
257
+ };
258
+ await new SetUpAscApiKey_1.SetUpAscApiKey(appLookupParams, AscApiKeyUtils_1.AppStoreApiKeyPurpose.SUBMISSION_SERVICE).runAsync(credentialsCtx);
259
+ const ascApp = await (0, ensureAppExists_1.ensureAppExistsAsync)(userAuthCtx, {
260
+ name: appName,
261
+ bundleIdentifier: bundleId,
351
262
  });
352
- // Set up push notifications (outside suppressed block so prompts are visible)
353
- const appLookupParamsForPushKey = { ...app, bundleIdentifier: bundleId };
354
- const setupPushKeyAction = new SetUpPushKey_1.SetUpPushKey(appLookupParamsForPushKey);
263
+ const setupPushKeyAction = new SetUpPushKey_1.SetUpPushKey(appLookupParams);
355
264
  const isPushKeySetup = await setupPushKeyAction.isPushKeySetupAsync(credentialsCtx);
356
265
  if (!isPushKeySetup) {
357
266
  if (customizeCreds) {
@@ -369,8 +278,16 @@ class Go extends EasCommand_1.default {
369
278
  }
370
279
  return ascApp;
371
280
  }
372
- async runWorkflowAsync(graphqlClient, projectDir, projectId, actor, vcsClient) {
373
- const account = actor.accounts[0];
281
+ async dispatchWorkflowAsync(graphqlClient, projectId, actor, bundleId, appName, ascAppId, sdkVersion, tmpDir, vcsClient) {
282
+ const account = (0, actions_1.ensureActorHasPrimaryAccount)(actor);
283
+ const repackConfig = await WorkflowRunQuery_1.WorkflowRunQuery.expoGoRepackConfigurationAsync(graphqlClient, {
284
+ appId: projectId,
285
+ ascAppId,
286
+ appName,
287
+ bundleId,
288
+ sdkVersion,
289
+ });
290
+ await Promise.all(repackConfig.files.map(f => fs.writeFile(path.join(tmpDir, f.fileName), f.fileContents)));
374
291
  const { projectArchiveBucketKey, easJsonBucketKey, packageJsonBucketKey } = await withSuppressedOutputAsync(async () => {
375
292
  const { projectArchiveBucketKey } = await (0, uploadAccountScopedProjectSourceAsync_1.uploadAccountScopedProjectSourceAsync)({
376
293
  graphqlClient,
@@ -380,30 +297,29 @@ class Go extends EasCommand_1.default {
380
297
  const { fileBucketKey: easJsonBucketKey } = await (0, uploadAccountScopedFileAsync_1.uploadAccountScopedFileAsync)({
381
298
  graphqlClient,
382
299
  accountId: account.id,
383
- filePath: path.join(projectDir, 'eas.json'),
300
+ filePath: path.join(tmpDir, 'eas.json'),
384
301
  maxSizeBytes: 1024 * 1024,
385
302
  });
386
303
  const { fileBucketKey: packageJsonBucketKey } = await (0, uploadAccountScopedFileAsync_1.uploadAccountScopedFileAsync)({
387
304
  graphqlClient,
388
305
  accountId: account.id,
389
- filePath: path.join(projectDir, 'package.json'),
306
+ filePath: path.join(tmpDir, 'package.json'),
390
307
  maxSizeBytes: 1024 * 1024,
391
308
  });
392
309
  return { projectArchiveBucketKey, easJsonBucketKey, packageJsonBucketKey };
393
310
  });
394
- const { id: workflowRunId } = await WorkflowRunMutation_1.WorkflowRunMutation.createExpoGoRepackWorkflowRunAsync(graphqlClient, {
311
+ const result = await WorkflowRunMutation_1.WorkflowRunMutation.createExpoGoRepackWorkflowRunAsync(graphqlClient, {
395
312
  appId: projectId,
313
+ sdkVersion: repackConfig.sdkVersion,
396
314
  projectSource: {
397
315
  type: generated_1.WorkflowProjectSourceType.Gcs,
398
316
  projectArchiveBucketKey,
399
317
  easJsonBucketKey,
400
318
  packageJsonBucketKey,
401
- projectRootDirectory: '.',
402
319
  },
403
320
  });
404
- const app = await AppQuery_1.AppQuery.byIdAsync(graphqlClient, projectId);
405
- const workflowUrl = `https://expo.dev/accounts/${account.name}/projects/${app.slug}/workflows/${workflowRunId}`;
406
- return { workflowUrl, workflowRunId };
321
+ const workflowUrl = (0, url_1.getWorkflowRunUrl)(account.name, deriveBundleIdSlug(bundleId), result.id);
322
+ return { workflowUrl, workflowRunId: result.id };
407
323
  }
408
324
  async monitorWorkflowJobsAsync(graphqlClient, workflowRunId) {
409
325
  const EXPECTED_BUILD_DURATION_SECONDS = 5 * 60;
@@ -426,8 +342,8 @@ class Go extends EasCommand_1.default {
426
342
  useCache: false,
427
343
  });
428
344
  failedFetchesCount = 0;
429
- const repackJob = workflowRun.jobs.find(j => j.name === 'Repack Expo Go');
430
- const submitJob = workflowRun.jobs.find(j => j.name === 'Submit to TestFlight');
345
+ const repackJob = workflowRun.jobs.find(j => j.key === 'build');
346
+ const submitJob = workflowRun.jobs.find(j => j.key === 'submit');
431
347
  if (!buildCompleted) {
432
348
  if (repackJob?.status === generated_1.WorkflowJobStatus.Success) {
433
349
  buildSpinner.succeed('Built Expo Go');
@@ -15002,6 +15002,7 @@ export type CreateWorkflowRunFromGitRefMutation = {
15002
15002
  export type CreateExpoGoRepackWorkflowRunMutationVariables = Exact<{
15003
15003
  appId: Scalars['ID']['input'];
15004
15004
  projectSource: WorkflowProjectSourceInput;
15005
+ sdkVersion?: InputMaybe<Scalars['String']['input']>;
15005
15006
  }>;
15006
15007
  export type CreateExpoGoRepackWorkflowRunMutation = {
15007
15008
  __typename?: 'RootMutation';
@@ -18232,6 +18233,24 @@ export type WorkflowJobByIdQuery = {
18232
18233
  };
18233
18234
  };
18234
18235
  };
18236
+ export type ExpoGoRepackConfigurationQueryVariables = Exact<{
18237
+ input: ExpoGoRepackInput;
18238
+ }>;
18239
+ export type ExpoGoRepackConfigurationQuery = {
18240
+ __typename?: 'RootQuery';
18241
+ expoGoBuild: {
18242
+ __typename?: 'ExpoGoBuildQuery';
18243
+ repackConfiguration: {
18244
+ __typename?: 'ExpoGoProjectConfiguration';
18245
+ sdkVersion: string;
18246
+ files: Array<{
18247
+ __typename?: 'ExpoGoProjectFile';
18248
+ fileName: string;
18249
+ fileContents: string;
18250
+ }>;
18251
+ };
18252
+ };
18253
+ };
18235
18254
  export type WorkflowRunByIdQueryVariables = Exact<{
18236
18255
  workflowRunId: Scalars['ID']['input'];
18237
18256
  }>;
@@ -15,8 +15,9 @@ export declare namespace WorkflowRunMutation {
15
15
  }): Promise<{
16
16
  id: string;
17
17
  }>;
18
- function createExpoGoRepackWorkflowRunAsync(graphqlClient: ExpoGraphqlClient, { appId, projectSource, }: {
18
+ function createExpoGoRepackWorkflowRunAsync(graphqlClient: ExpoGraphqlClient, { appId, sdkVersion, projectSource, }: {
19
19
  appId: string;
20
+ sdkVersion?: string;
20
21
  projectSource: WorkflowProjectSourceInput;
21
22
  }): Promise<{
22
23
  id: string;
@@ -60,21 +60,29 @@ var WorkflowRunMutation;
60
60
  return { id: data.workflowRun.createWorkflowRunFromGitRef.id };
61
61
  }
62
62
  WorkflowRunMutation.createWorkflowRunFromGitRefAsync = createWorkflowRunFromGitRefAsync;
63
- async function createExpoGoRepackWorkflowRunAsync(graphqlClient, { appId, projectSource, }) {
63
+ async function createExpoGoRepackWorkflowRunAsync(graphqlClient, { appId, sdkVersion, projectSource, }) {
64
64
  const data = await (0, client_1.withErrorHandlingAsync)(graphqlClient
65
65
  .mutation(
66
66
  /* eslint-disable graphql/template-strings */
67
67
  (0, graphql_tag_1.default) `
68
- mutation CreateExpoGoRepackWorkflowRun($appId: ID!, $projectSource: WorkflowProjectSourceInput!) {
68
+ mutation CreateExpoGoRepackWorkflowRun(
69
+ $appId: ID!
70
+ $projectSource: WorkflowProjectSourceInput!
71
+ $sdkVersion: String
72
+ ) {
69
73
  workflowRun {
70
- createExpoGoRepackWorkflowRun(appId: $appId, projectSource: $projectSource) {
74
+ createExpoGoRepackWorkflowRun(
75
+ appId: $appId
76
+ projectSource: $projectSource
77
+ sdkVersion: $sdkVersion
78
+ ) {
71
79
  id
72
80
  }
73
81
  }
74
82
  }
75
83
  `,
76
84
  /* eslint-enable graphql/template-strings */
77
- { appId, projectSource })
85
+ { appId, projectSource, sdkVersion })
78
86
  .toPromise());
79
87
  return { id: data.workflowRun.createExpoGoRepackWorkflowRun.id };
80
88
  }
@@ -1,6 +1,7 @@
1
1
  import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
2
- import { WorkflowRunByIdQuery, WorkflowRunByIdWithJobsQuery, WorkflowRunFragment, WorkflowRunStatus } from '../generated';
2
+ import { ExpoGoProjectConfiguration, ExpoGoRepackInput, WorkflowRunByIdQuery, WorkflowRunByIdWithJobsQuery, WorkflowRunFragment, WorkflowRunStatus } from '../generated';
3
3
  export declare const WorkflowRunQuery: {
4
+ expoGoRepackConfigurationAsync(graphqlClient: ExpoGraphqlClient, input: ExpoGoRepackInput): Promise<ExpoGoProjectConfiguration>;
4
5
  byIdAsync(graphqlClient: ExpoGraphqlClient, workflowRunId: string, { useCache }?: {
5
6
  useCache?: boolean;
6
7
  }): Promise<WorkflowRunByIdQuery["workflowRuns"]["byId"]>;
@@ -9,6 +9,28 @@ const client_1 = require("../client");
9
9
  const WorkflowJob_1 = require("../types/WorkflowJob");
10
10
  const WorkflowRun_1 = require("../types/WorkflowRun");
11
11
  exports.WorkflowRunQuery = {
12
+ async expoGoRepackConfigurationAsync(graphqlClient, input) {
13
+ const data = await (0, client_1.withErrorHandlingAsync)(graphqlClient
14
+ .query(
15
+ /* eslint-disable graphql/template-strings */
16
+ (0, graphql_tag_1.default) `
17
+ query ExpoGoRepackConfiguration($input: ExpoGoRepackInput!) {
18
+ expoGoBuild {
19
+ repackConfiguration(input: $input) {
20
+ sdkVersion
21
+ files {
22
+ fileName
23
+ fileContents
24
+ }
25
+ }
26
+ }
27
+ }
28
+ `,
29
+ /* eslint-enable graphql/template-strings */
30
+ { input }, { requestPolicy: 'network-only' })
31
+ .toPromise());
32
+ return data.expoGoBuild.repackConfiguration;
33
+ },
12
34
  async byIdAsync(graphqlClient, workflowRunId, { useCache = true } = {}) {
13
35
  const data = await (0, client_1.withErrorHandlingAsync)(graphqlClient
14
36
  .query((0, graphql_tag_1.default) `
@@ -27,14 +27,14 @@ class NoVcsClient extends vcs_1.Client {
27
27
  })).stdout.trim();
28
28
  }
29
29
  catch (err) {
30
- if (!hasWarnedAboutEasProjectRoot) {
30
+ if (!this.cwdOverride && !hasWarnedAboutEasProjectRoot) {
31
31
  log_1.default.warn(`Failed to get Git root path with \`git rev-parse --show-toplevel\`.`, err);
32
32
  log_1.default.warn('Falling back to using current working directory as project root.');
33
33
  log_1.default.warn('You can set `EAS_PROJECT_ROOT` environment variable to let eas-cli know where your project is located.');
34
34
  hasWarnedAboutEasProjectRoot = true;
35
35
  }
36
36
  }
37
- return path_1.default.resolve(process.cwd(), process.env.EAS_PROJECT_ROOT ?? '.');
37
+ return path_1.default.resolve(this.cwdOverride ?? process.cwd(), process.env.EAS_PROJECT_ROOT ?? '.');
38
38
  }
39
39
  async makeShallowCopyAsync(destinationPath) {
40
40
  const srcPath = path_1.default.normalize(await this.getRootPathAsync());