eas-cli 15.0.15 → 16.0.0

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,11 +5,13 @@ export declare class ApiV2Error extends Error {
5
5
  readonly expoApiV2ErrorDetails?: JSONValue;
6
6
  readonly expoApiV2ErrorServerStack?: string;
7
7
  readonly expoApiV2ErrorMetadata?: object;
8
+ readonly expoApiV2ErrorRequestId?: string;
8
9
  constructor(response: {
9
10
  message: string;
10
11
  code: string;
11
12
  stack?: string;
12
13
  details?: JSONValue;
13
14
  metadata?: object;
15
+ requestId?: string;
14
16
  });
15
17
  }
@@ -7,12 +7,14 @@ class ApiV2Error extends Error {
7
7
  expoApiV2ErrorDetails;
8
8
  expoApiV2ErrorServerStack;
9
9
  expoApiV2ErrorMetadata;
10
+ expoApiV2ErrorRequestId;
10
11
  constructor(response) {
11
12
  super(response.message);
12
13
  this.expoApiV2ErrorCode = response.code;
13
14
  this.expoApiV2ErrorDetails = response.details;
14
15
  this.expoApiV2ErrorServerStack = response.stack;
15
16
  this.expoApiV2ErrorMetadata = response.metadata;
17
+ this.expoApiV2ErrorRequestId = response.requestId;
16
18
  }
17
19
  }
18
20
  exports.ApiV2Error = ApiV2Error;
@@ -17,6 +17,7 @@ const repository_1 = require("./utils/repository");
17
17
  const AnalyticsManager_1 = require("../analytics/AnalyticsManager");
18
18
  const common_1 = require("../analytics/common");
19
19
  const api_1 = require("../api");
20
+ const cli_1 = require("../fingerprint/cli");
20
21
  const generated_1 = require("../graphql/generated");
21
22
  const BuildMutation_1 = require("../graphql/mutations/BuildMutation");
22
23
  const BuildQuery_1 = require("../graphql/queries/BuildQuery");
@@ -27,7 +28,6 @@ const maybeUploadFingerprintAsync_1 = require("../project/maybeUploadFingerprint
27
28
  const resolveRuntimeVersionAsync_1 = require("../project/resolveRuntimeVersionAsync");
28
29
  const uploads_1 = require("../uploads");
29
30
  const files_1 = require("../utils/files");
30
- const fingerprintCli_1 = require("../utils/fingerprintCli");
31
31
  const json_1 = require("../utils/json");
32
32
  const progress_1 = require("../utils/progress");
33
33
  const promise_1 = require("../utils/promise");
@@ -479,7 +479,7 @@ async function computeAndMaybeUploadFingerprintFromExpoUpdatesAsync(ctx) {
479
479
  };
480
480
  }
481
481
  async function computeAndMaybeUploadFingerprintWithoutExpoUpdatesAsync(ctx, { debug } = {}) {
482
- const fingerprint = await (0, fingerprintCli_1.createFingerprintAsync)(ctx.projectDir, {
482
+ const fingerprint = await (0, cli_1.createFingerprintAsync)(ctx.projectDir, {
483
483
  workflow: ctx.workflow,
484
484
  platforms: [ctx.platform],
485
485
  env: ctx.env,
@@ -10,6 +10,7 @@ const evaluateConfigWithEnvVarsAsync_1 = require("../../build/evaluateConfigWith
10
10
  const runBuildAndSubmit_1 = require("../../build/runBuildAndSubmit");
11
11
  const repository_1 = require("../../build/utils/repository");
12
12
  const EasCommand_1 = tslib_1.__importDefault(require("../../commandUtils/EasCommand"));
13
+ const cli_1 = require("../../fingerprint/cli");
13
14
  const generated_1 = require("../../graphql/generated");
14
15
  const BuildQuery_1 = require("../../graphql/queries/BuildQuery");
15
16
  const AppPlatform_1 = require("../../graphql/types/AppPlatform");
@@ -18,7 +19,6 @@ const platform_1 = require("../../platform");
18
19
  const workflow_1 = require("../../project/workflow");
19
20
  const prompts_1 = require("../../prompts");
20
21
  const expoCli_1 = require("../../utils/expoCli");
21
- const fingerprintCli_1 = require("../../utils/fingerprintCli");
22
22
  const profiles_1 = require("../../utils/profiles");
23
23
  const DEFAULT_EAS_BUILD_RUN_PROFILE_NAME = 'development-simulator';
24
24
  class BuildDev extends EasCommand_1.default {
@@ -74,7 +74,7 @@ class BuildDev extends EasCommand_1.default {
74
74
  getProjectConfig: getDynamicPrivateProjectConfigAsync,
75
75
  opts: { env: buildProfile.profile.env },
76
76
  });
77
- const fingerprint = await (0, fingerprintCli_1.createFingerprintAsync)(projectDir, {
77
+ const fingerprint = await (0, cli_1.createFingerprintAsync)(projectDir, {
78
78
  env,
79
79
  workflow,
80
80
  platforms: [platform],
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.selectBuildToCompareAsync = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const eas_build_job_1 = require("@expo/eas-build-job");
6
5
  const core_1 = require("@oclif/core");
7
6
  const better_opn_1 = tslib_1.__importDefault(require("better-opn"));
8
7
  const chalk_1 = tslib_1.__importDefault(require("chalk"));
@@ -11,21 +10,18 @@ const queries_1 = require("../../branch/queries");
11
10
  const EasCommand_1 = tslib_1.__importDefault(require("../../commandUtils/EasCommand"));
12
11
  const builds_1 = require("../../commandUtils/builds");
13
12
  const flags_1 = require("../../commandUtils/flags");
14
- const generated_1 = require("../../graphql/generated");
15
- const FingerprintMutation_1 = require("../../graphql/mutations/FingerprintMutation");
13
+ const cli_1 = require("../../fingerprint/cli");
14
+ const diff_1 = require("../../fingerprint/diff");
15
+ const utils_1 = require("../../fingerprint/utils");
16
16
  const AppQuery_1 = require("../../graphql/queries/AppQuery");
17
17
  const BuildQuery_1 = require("../../graphql/queries/BuildQuery");
18
18
  const FingerprintQuery_1 = require("../../graphql/queries/FingerprintQuery");
19
19
  const UpdateQuery_1 = require("../../graphql/queries/UpdateQuery");
20
20
  const log_1 = tslib_1.__importStar(require("../../log"));
21
21
  const ora_1 = require("../../ora");
22
- const maybeUploadFingerprintAsync_1 = require("../../project/maybeUploadFingerprintAsync");
23
22
  const projectUtils_1 = require("../../project/projectUtils");
24
- const workflow_1 = require("../../project/workflow");
25
23
  const prompts_1 = require("../../prompts");
26
24
  const queries_2 = require("../../update/queries");
27
- const fingerprintCli_1 = require("../../utils/fingerprintCli");
28
- const fingerprintDiff_1 = require("../../utils/fingerprintDiff");
29
25
  const formatFields_1 = tslib_1.__importDefault(require("../../utils/formatFields"));
30
26
  const json_1 = require("../../utils/json");
31
27
  var FingerprintOriginType;
@@ -122,7 +118,7 @@ class FingerprintCompare extends EasCommand_1.default {
122
118
  else {
123
119
  log_1.default.log(`🔄 ${capitalizeFirstLetter(prettyPrintFingerprint(firstFingerprint, firstFingerprintOrigin))} differs from ${prettyPrintFingerprint(secondFingerprint, secondFingerprintOrigin)}`);
124
120
  }
125
- const fingerprintDiffs = (0, fingerprintCli_1.diffFingerprint)(projectDir, firstFingerprint, secondFingerprint);
121
+ const fingerprintDiffs = (0, cli_1.diffFingerprint)(projectDir, firstFingerprint, secondFingerprint);
126
122
  if (!fingerprintDiffs) {
127
123
  log_1.default.error('Fingerprint diffs can only be computed for projects with SDK 52 or higher');
128
124
  return;
@@ -278,30 +274,8 @@ async function getFingerprintInfoFromLocalProjectAsync(graphqlClient, projectDir
278
274
  if (!firstFingerprintPlatforms) {
279
275
  throw new Error(`Cannot compare the local directory against the provided fingerprint hash "${firstFingerprintInfo.fingerprint.hash}" because the associated platform could not be determined. Ensure the fingerprint is linked to a build or update to identify the platform.`);
280
276
  }
281
- const workflows = await (0, workflow_1.resolveWorkflowPerPlatformAsync)(projectDir, vcsClient);
282
- const optionsFromWorkflow = getFingerprintOptionsFromWorkflow(firstFingerprintPlatforms, workflows);
283
- const projectFingerprint = await (0, fingerprintCli_1.createFingerprintAsync)(projectDir, {
284
- ...optionsFromWorkflow,
285
- platforms: firstFingerprintPlatforms.map(appPlatformToString),
286
- debug: true,
287
- env: undefined,
288
- });
289
- if (!projectFingerprint) {
290
- throw new Error('Project fingerprints can only be computed for projects with SDK 52 or higher');
291
- }
292
- const uploadedFingerprint = await (0, maybeUploadFingerprintAsync_1.maybeUploadFingerprintAsync)({
293
- hash: projectFingerprint.hash,
294
- fingerprint: {
295
- fingerprintSources: projectFingerprint.sources,
296
- isDebugFingerprintSource: log_1.default.isDebug,
297
- },
298
- graphqlClient,
299
- });
300
- await FingerprintMutation_1.FingerprintMutation.createFingerprintAsync(graphqlClient, projectId, {
301
- hash: uploadedFingerprint.hash,
302
- source: uploadedFingerprint.fingerprintSource,
303
- });
304
- return { fingerprint: projectFingerprint, origin: { type: FingerprintOriginType.Project } };
277
+ const fingerprint = await (0, utils_1.getFingerprintInfoFromLocalProjectForPlatformsAsync)(graphqlClient, projectDir, projectId, vcsClient, firstFingerprintPlatforms);
278
+ return { fingerprint, origin: { type: FingerprintOriginType.Project } };
305
279
  }
306
280
  async function getFingerprintFromUpdateFragmentAsync(updateWithFingerprint) {
307
281
  if (!updateWithFingerprint.fingerprint) {
@@ -312,7 +286,7 @@ async function getFingerprintFromUpdateFragmentAsync(updateWithFingerprint) {
312
286
  }
313
287
  return {
314
288
  fingerprint: await getFingerprintFromFingerprintFragmentAsync(updateWithFingerprint.fingerprint),
315
- platforms: [stringToAppPlatform(updateWithFingerprint.platform)],
289
+ platforms: [(0, utils_1.stringToAppPlatform)(updateWithFingerprint.platform)],
316
290
  origin: {
317
291
  type: FingerprintOriginType.Update,
318
292
  update: updateWithFingerprint,
@@ -329,7 +303,7 @@ async function getFingerprintInfoFromHashAsync(graphqlClient, projectId, hash) {
329
303
  platforms = [fingerprintBuilds[0].platform];
330
304
  }
331
305
  else if (fingerprintUpdates.length > 0) {
332
- platforms = [stringToAppPlatform(fingerprintUpdates[0].platform)];
306
+ platforms = [(0, utils_1.stringToAppPlatform)(fingerprintUpdates[0].platform)];
333
307
  }
334
308
  return {
335
309
  fingerprint,
@@ -409,28 +383,6 @@ async function getFingerprintFromFingerprintFragmentAsync(fingerprintFragment) {
409
383
  const fingerprintResponse = await fetch(fingerprintDebugUrl);
410
384
  return (await fingerprintResponse.json());
411
385
  }
412
- function getFingerprintOptionsFromWorkflow(platforms, workflowsByPlatform) {
413
- if (platforms.length === 0) {
414
- throw new Error('Could not determine platform from fingerprint sources');
415
- }
416
- // Single platform case
417
- if (platforms.length === 1) {
418
- const platform = platforms[0];
419
- return { workflow: workflowsByPlatform[appPlatformToPlatform(platform)] };
420
- }
421
- // Multiple platforms case
422
- const workflows = platforms.map(platform => workflowsByPlatform[appPlatformToPlatform(platform)]);
423
- // If all workflows are the same, return the common workflow
424
- const [firstWorkflow, ...restWorkflows] = workflows;
425
- if (restWorkflows.every(workflow => workflow === firstWorkflow)) {
426
- return { workflow: firstWorkflow };
427
- }
428
- // Generate ignorePaths for mixed workflows
429
- const ignorePaths = platforms
430
- .filter(platform => workflowsByPlatform[appPlatformToPlatform(platform)] === eas_build_job_1.Workflow.MANAGED)
431
- .map(platform => `${appPlatformToString(platform)}/**/*`);
432
- return { ignorePaths };
433
- }
434
386
  function printContentDiff(diff) {
435
387
  if (diff.op === 'added') {
436
388
  const sourceType = diff.addedSource.type;
@@ -562,14 +514,14 @@ function printContentsDiff(contents1, contents2) {
562
514
  const prettifiedContents2 = isStr2JSON
563
515
  ? JSON.stringify(JSON.parse(stringifiedContents2), null, 2)
564
516
  : stringifiedContents2;
565
- (0, fingerprintDiff_1.abridgedDiff)(prettifiedContents1, prettifiedContents2, 0);
517
+ (0, diff_1.abridgedDiff)(prettifiedContents1, prettifiedContents2, 0);
566
518
  }
567
519
  function prettyPrintFingerprint(fingerprint, origin) {
568
520
  if (origin.type === FingerprintOriginType.Project) {
569
521
  return `fingerprint ${fingerprint.hash} from local directory`;
570
522
  }
571
523
  else if (origin.type === FingerprintOriginType.Update) {
572
- return `fingerprint ${fingerprint.hash} from ${origin.update?.platform ? stringToAppPlatform(origin.update?.platform) : ''} ${origin.type}`;
524
+ return `fingerprint ${fingerprint.hash} from ${origin.update?.platform ? (0, utils_1.stringToAppPlatform)(origin.update?.platform) : ''} ${origin.type}`;
573
525
  }
574
526
  else if (origin.type === FingerprintOriginType.Build) {
575
527
  return `fingerprint ${fingerprint.hash} from ${origin.build?.platform} ${origin.type}`;
@@ -588,36 +540,6 @@ function isJSON(str) {
588
540
  return false;
589
541
  }
590
542
  }
591
- function appPlatformToPlatform(platform) {
592
- switch (platform) {
593
- case generated_1.AppPlatform.Android:
594
- return eas_build_job_1.Platform.ANDROID;
595
- case generated_1.AppPlatform.Ios:
596
- return eas_build_job_1.Platform.IOS;
597
- default:
598
- throw new Error(`Unsupported platform: ${platform}`);
599
- }
600
- }
601
- function appPlatformToString(platform) {
602
- switch (platform) {
603
- case generated_1.AppPlatform.Android:
604
- return 'android';
605
- case generated_1.AppPlatform.Ios:
606
- return 'ios';
607
- default:
608
- throw new Error(`Unsupported platform: ${platform}`);
609
- }
610
- }
611
- function stringToAppPlatform(platform) {
612
- switch (platform) {
613
- case 'android':
614
- return generated_1.AppPlatform.Android;
615
- case 'ios':
616
- return generated_1.AppPlatform.Ios;
617
- default:
618
- throw new Error(`Unsupported platform: ${platform}`);
619
- }
620
- }
621
543
  async function selectBuildToCompareAsync(graphqlClient, projectId, projectDisplayName, { filters, } = {}) {
622
544
  const spinner = (0, ora_1.ora)().start('Fetching builds…');
623
545
  let builds;
@@ -0,0 +1,21 @@
1
+ import EasCommand from '../../commandUtils/EasCommand';
2
+ import { AppPlatform } from '../../graphql/generated';
3
+ export default class FingerprintGenerate extends EasCommand {
4
+ static description: string;
5
+ static strict: boolean;
6
+ static hidden: boolean;
7
+ static examples: string[];
8
+ static flags: {
9
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
10
+ 'non-interactive': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
11
+ platform: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
12
+ };
13
+ static contextDefinition: {
14
+ vcsClient: import("../../commandUtils/context/VcsClientContextField").default;
15
+ loggedIn: import("../../commandUtils/context/LoggedInContextField").default;
16
+ privateProjectConfig: import("../../commandUtils/context/PrivateProjectConfigContextField").PrivateProjectConfigContextField;
17
+ projectId: import("../../commandUtils/context/ProjectIdContextField").ProjectIdContextField;
18
+ };
19
+ runAsync(): Promise<void>;
20
+ }
21
+ export declare function selectRequestedPlatformAsync(): Promise<AppPlatform>;
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.selectRequestedPlatformAsync = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const core_1 = require("@oclif/core");
6
+ const api_1 = require("../../api");
7
+ const EasCommand_1 = tslib_1.__importDefault(require("../../commandUtils/EasCommand"));
8
+ const flags_1 = require("../../commandUtils/flags");
9
+ const utils_1 = require("../../fingerprint/utils");
10
+ const generated_1 = require("../../graphql/generated");
11
+ const AppQuery_1 = require("../../graphql/queries/AppQuery");
12
+ const log_1 = tslib_1.__importStar(require("../../log"));
13
+ const prompts_1 = require("../../prompts");
14
+ const json_1 = require("../../utils/json");
15
+ class FingerprintGenerate extends EasCommand_1.default {
16
+ static description = 'generate fingerprints from the current project';
17
+ static strict = false;
18
+ static hidden = true;
19
+ static examples = [
20
+ '$ eas fingerprint:generate',
21
+ '$ eas fingerprint:generate --json --non-interactive -p android',
22
+ ];
23
+ static flags = {
24
+ platform: core_1.Flags.enum({
25
+ char: 'p',
26
+ options: ['android', 'ios'],
27
+ }),
28
+ ...flags_1.EasNonInteractiveAndJsonFlags,
29
+ };
30
+ static contextDefinition = {
31
+ ...this.ContextOptions.ProjectId,
32
+ ...this.ContextOptions.ProjectConfig,
33
+ ...this.ContextOptions.LoggedIn,
34
+ ...this.ContextOptions.Vcs,
35
+ };
36
+ async runAsync() {
37
+ const { flags } = await this.parse(FingerprintGenerate);
38
+ const { json, 'non-interactive': nonInteractive, platform: platformStringFlag } = flags;
39
+ const { projectId, privateProjectConfig: { projectDir }, loggedIn: { graphqlClient }, vcsClient, } = await this.getContextAsync(FingerprintGenerate, {
40
+ nonInteractive,
41
+ withServerSideEnvironment: null,
42
+ });
43
+ if (json) {
44
+ (0, json_1.enableJsonOutput)();
45
+ }
46
+ let platform;
47
+ if (platformStringFlag) {
48
+ platform = (0, utils_1.stringToAppPlatform)(platformStringFlag);
49
+ }
50
+ else {
51
+ if (nonInteractive) {
52
+ throw new Error('Platform must be specified in non-interactive mode with the --p flag');
53
+ }
54
+ platform = await selectRequestedPlatformAsync();
55
+ }
56
+ const fingerprint = await (0, utils_1.getFingerprintInfoFromLocalProjectForPlatformsAsync)(graphqlClient, projectDir, projectId, vcsClient, [platform]);
57
+ if (json) {
58
+ (0, json_1.printJsonOnlyOutput)(fingerprint);
59
+ return;
60
+ }
61
+ log_1.default.log(`✅ Fingerprint generated: ${fingerprint.hash}`);
62
+ const project = await AppQuery_1.AppQuery.byIdAsync(graphqlClient, projectId);
63
+ const fingerprintUrl = new URL(`/accounts/${project.ownerAccount.name}/projects/${project.slug}/fingerprints/${fingerprint.hash}`, (0, api_1.getExpoWebsiteBaseUrl)());
64
+ log_1.default.log(`🔍 View the fingerprint at ${(0, log_1.link)(fingerprintUrl.toString())}`);
65
+ log_1.default.log(`💡 If you want to see the entire fingerprint output, pass in the --json flag.`);
66
+ }
67
+ }
68
+ exports.default = FingerprintGenerate;
69
+ async function selectRequestedPlatformAsync() {
70
+ const { requestedPlatform } = await (0, prompts_1.promptAsync)({
71
+ type: 'select',
72
+ message: 'Select platform',
73
+ name: 'requestedPlatform',
74
+ choices: [
75
+ { title: 'Android', value: generated_1.AppPlatform.Android },
76
+ { title: 'iOS', value: generated_1.AppPlatform.Ios },
77
+ ],
78
+ });
79
+ return requestedPlatform;
80
+ }
81
+ exports.selectRequestedPlatformAsync = selectRequestedPlatformAsync;
@@ -1,5 +1,5 @@
1
1
  import { Env, Workflow } from '@expo/eas-build-job';
2
- import { Fingerprint, FingerprintDiffItem } from './fingerprint';
2
+ import { Fingerprint, FingerprintDiffItem } from './types';
3
3
  export type FingerprintOptions = {
4
4
  workflow?: Workflow;
5
5
  platforms: string[];
@@ -4,9 +4,9 @@ exports.createFingerprintsByKeyAsync = exports.createFingerprintAsync = exports.
4
4
  const tslib_1 = require("tslib");
5
5
  const eas_build_job_1 = require("@expo/eas-build-job");
6
6
  const resolve_from_1 = require("resolve-from");
7
- const mapMapAsync_1 = tslib_1.__importDefault(require("./expodash/mapMapAsync"));
8
7
  const log_1 = tslib_1.__importDefault(require("../log"));
9
8
  const ora_1 = require("../ora");
9
+ const mapMapAsync_1 = tslib_1.__importDefault(require("../utils/expodash/mapMapAsync"));
10
10
  function diffFingerprint(projectDir, fingerprint1, fingerprint2) {
11
11
  // @expo/fingerprint is exported in the expo package for SDK 52+
12
12
  const fingerprintPath = (0, resolve_from_1.silent)(projectDir, 'expo/fingerprint');
@@ -0,0 +1,9 @@
1
+ import { Platform } from '@expo/eas-build-job';
2
+ import { Fingerprint } from './types';
3
+ import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
4
+ import { AppPlatform } from '../graphql/generated';
5
+ import { Client } from '../vcs/vcs';
6
+ export declare function getFingerprintInfoFromLocalProjectForPlatformsAsync(graphqlClient: ExpoGraphqlClient, projectDir: string, projectId: string, vcsClient: Client, platforms: AppPlatform[]): Promise<Fingerprint>;
7
+ export declare function appPlatformToPlatform(platform: AppPlatform): Platform;
8
+ export declare function appPlatformToString(platform: AppPlatform): string;
9
+ export declare function stringToAppPlatform(platform: string): AppPlatform;
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.stringToAppPlatform = exports.appPlatformToString = exports.appPlatformToPlatform = exports.getFingerprintInfoFromLocalProjectForPlatformsAsync = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const eas_build_job_1 = require("@expo/eas-build-job");
6
+ const cli_1 = require("./cli");
7
+ const generated_1 = require("../graphql/generated");
8
+ const FingerprintMutation_1 = require("../graphql/mutations/FingerprintMutation");
9
+ const log_1 = tslib_1.__importDefault(require("../log"));
10
+ const maybeUploadFingerprintAsync_1 = require("../project/maybeUploadFingerprintAsync");
11
+ const workflow_1 = require("../project/workflow");
12
+ async function getFingerprintInfoFromLocalProjectForPlatformsAsync(graphqlClient, projectDir, projectId, vcsClient, platforms) {
13
+ const workflows = await (0, workflow_1.resolveWorkflowPerPlatformAsync)(projectDir, vcsClient);
14
+ const optionsFromWorkflow = getFingerprintOptionsFromWorkflow(platforms, workflows);
15
+ const projectFingerprint = await (0, cli_1.createFingerprintAsync)(projectDir, {
16
+ ...optionsFromWorkflow,
17
+ platforms: platforms.map(appPlatformToString),
18
+ debug: true,
19
+ env: undefined,
20
+ });
21
+ if (!projectFingerprint) {
22
+ throw new Error('Project fingerprints can only be computed for projects with SDK 52 or higher');
23
+ }
24
+ const uploadedFingerprint = await (0, maybeUploadFingerprintAsync_1.maybeUploadFingerprintAsync)({
25
+ hash: projectFingerprint.hash,
26
+ fingerprint: {
27
+ fingerprintSources: projectFingerprint.sources,
28
+ isDebugFingerprintSource: log_1.default.isDebug,
29
+ },
30
+ graphqlClient,
31
+ });
32
+ await FingerprintMutation_1.FingerprintMutation.createFingerprintAsync(graphqlClient, projectId, {
33
+ hash: uploadedFingerprint.hash,
34
+ source: uploadedFingerprint.fingerprintSource,
35
+ });
36
+ return projectFingerprint;
37
+ }
38
+ exports.getFingerprintInfoFromLocalProjectForPlatformsAsync = getFingerprintInfoFromLocalProjectForPlatformsAsync;
39
+ function getFingerprintOptionsFromWorkflow(platforms, workflowsByPlatform) {
40
+ if (platforms.length === 0) {
41
+ throw new Error('Could not determine platform from fingerprint sources');
42
+ }
43
+ // Single platform case
44
+ if (platforms.length === 1) {
45
+ const platform = platforms[0];
46
+ return { workflow: workflowsByPlatform[appPlatformToPlatform(platform)] };
47
+ }
48
+ // Multiple platforms case
49
+ const workflows = platforms.map(platform => workflowsByPlatform[appPlatformToPlatform(platform)]);
50
+ // If all workflows are the same, return the common workflow
51
+ const [firstWorkflow, ...restWorkflows] = workflows;
52
+ if (restWorkflows.every(workflow => workflow === firstWorkflow)) {
53
+ return { workflow: firstWorkflow };
54
+ }
55
+ // Generate ignorePaths for mixed workflows
56
+ const ignorePaths = platforms
57
+ .filter(platform => workflowsByPlatform[appPlatformToPlatform(platform)] === eas_build_job_1.Workflow.MANAGED)
58
+ .map(platform => `${appPlatformToString(platform)}/**/*`);
59
+ return { ignorePaths };
60
+ }
61
+ function appPlatformToPlatform(platform) {
62
+ switch (platform) {
63
+ case generated_1.AppPlatform.Android:
64
+ return eas_build_job_1.Platform.ANDROID;
65
+ case generated_1.AppPlatform.Ios:
66
+ return eas_build_job_1.Platform.IOS;
67
+ default:
68
+ throw new Error(`Unsupported platform: ${platform}`);
69
+ }
70
+ }
71
+ exports.appPlatformToPlatform = appPlatformToPlatform;
72
+ function appPlatformToString(platform) {
73
+ switch (platform) {
74
+ case generated_1.AppPlatform.Android:
75
+ return 'android';
76
+ case generated_1.AppPlatform.Ios:
77
+ return 'ios';
78
+ default:
79
+ throw new Error(`Unsupported platform: ${platform}`);
80
+ }
81
+ }
82
+ exports.appPlatformToString = appPlatformToString;
83
+ function stringToAppPlatform(platform) {
84
+ switch (platform) {
85
+ case 'android':
86
+ return generated_1.AppPlatform.Android;
87
+ case 'ios':
88
+ return generated_1.AppPlatform.Ios;
89
+ default:
90
+ throw new Error(`Unsupported platform: ${platform}`);
91
+ }
92
+ }
93
+ exports.stringToAppPlatform = stringToAppPlatform;
@@ -19,6 +19,7 @@ const projectUtils_1 = require("./projectUtils");
19
19
  const resolveRuntimeVersionAsync_1 = require("./resolveRuntimeVersionAsync");
20
20
  const queries_1 = require("../branch/queries");
21
21
  const utils_1 = require("../branch/utils");
22
+ const cli_1 = require("../fingerprint/cli");
22
23
  const generated_1 = require("../graphql/generated");
23
24
  const PublishMutation_1 = require("../graphql/mutations/PublishMutation");
24
25
  const BranchQuery_1 = require("../graphql/queries/BranchQuery");
@@ -36,7 +37,6 @@ const filter_1 = require("../utils/expodash/filter");
36
37
  const groupBy_1 = tslib_1.__importDefault(require("../utils/expodash/groupBy"));
37
38
  const mapMapAsync_1 = tslib_1.__importDefault(require("../utils/expodash/mapMapAsync"));
38
39
  const uniqBy_1 = tslib_1.__importDefault(require("../utils/expodash/uniqBy"));
39
- const fingerprintCli_1 = require("../utils/fingerprintCli");
40
40
  const fileMetadataJoi = joi_1.default.object({
41
41
  assets: joi_1.default.array()
42
42
  .required()
@@ -551,7 +551,7 @@ async function maybeCalculateFingerprintForRuntimeVersionInfoObjectsWithoutExpoU
551
551
  fingerprintOptionsByRuntimeAndPlatform.set(runtimeAndPlatform, options);
552
552
  }
553
553
  }
554
- const fingerprintsByRuntimeAndPlatform = await (0, fingerprintCli_1.createFingerprintsByKeyAsync)(projectDir, fingerprintOptionsByRuntimeAndPlatform);
554
+ const fingerprintsByRuntimeAndPlatform = await (0, cli_1.createFingerprintsByKeyAsync)(projectDir, fingerprintOptionsByRuntimeAndPlatform);
555
555
  const uploadedFingerprintsByRuntimeAndPlatform = await (0, mapMapAsync_1.default)(fingerprintsByRuntimeAndPlatform, async (fingerprint) => {
556
556
  return {
557
557
  ...fingerprint,
@@ -6,7 +6,7 @@ function isAab(build) {
6
6
  return build.artifacts?.applicationArchiveUrl?.endsWith('.aab') ?? false;
7
7
  }
8
8
  function didArtifactsExpire(build) {
9
- return new Date().getTime() - new Date(build.completedAt).getTime() > 30 * 24 * 60 * 60 * 1000; // 30 days
9
+ return new Date().getTime() > new Date(build.expirationDate).getTime();
10
10
  }
11
11
  function isRunnableOnSimulatorOrEmulator(build) {
12
12
  return (build.status === generated_1.BuildStatus.Finished &&
@@ -7,6 +7,7 @@ const spawn_async_1 = tslib_1.__importDefault(require("@expo/spawn-async"));
7
7
  const core_1 = require("@oclif/core");
8
8
  const chalk_1 = tslib_1.__importDefault(require("chalk"));
9
9
  const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
10
+ const getenv_1 = tslib_1.__importDefault(require("getenv"));
10
11
  const path_1 = tslib_1.__importDefault(require("path"));
11
12
  const log_1 = tslib_1.__importStar(require("../../log"));
12
13
  const ora_1 = require("../../ora");
@@ -14,6 +15,7 @@ const prompts_1 = require("../../prompts");
14
15
  const git_1 = require("../git");
15
16
  const local_1 = require("../local");
16
17
  const vcs_1 = require("../vcs");
18
+ let hasWarnedAboutEasignoreInRequireCommit = false;
17
19
  class GitClient extends vcs_1.Client {
18
20
  maybeCwdOverride;
19
21
  requireCommit;
@@ -119,10 +121,11 @@ class GitClient extends vcs_1.Client {
119
121
  const rootPath = await this.getRootPathAsync();
120
122
  const sourceEasignorePath = path_1.default.join(rootPath, local_1.EASIGNORE_FILENAME);
121
123
  const doesEasignoreExist = await fs_extra_1.default.exists(sourceEasignorePath);
122
- if (this.requireCommit && doesEasignoreExist) {
123
- log_1.default.error(`".easignore" file is not supported if you also have "requireCommit" set to "true" in "eas.json".`);
124
- log_1.default.error(`Remove "${sourceEasignorePath}" and use ".gitignore" instead. ${(0, log_1.learnMore)('https://expo.fyi/eas-build-archive')}`);
125
- throw new Error(`Detected ".easignore" file ${sourceEasignorePath} while in "requireCommit = true" mode.`);
124
+ const shouldSuppressWarning = hasWarnedAboutEasignoreInRequireCommit ||
125
+ getenv_1.default.boolish('EAS_SUPPRESS_REQUIRE_COMMIT_EASIGNORE_WARNING', false);
126
+ if (this.requireCommit && doesEasignoreExist && !shouldSuppressWarning) {
127
+ log_1.default.warn(`You have "requireCommit: true" in "eas.json" and also ".easignore". If ".easignore" does remove files, note that the repository checked out in EAS will not longer be Git-clean.`);
128
+ hasWarnedAboutEasignoreInRequireCommit = true;
126
129
  }
127
130
  let gitRepoUri;
128
131
  if (process.platform === 'win32') {
@@ -6,6 +6,7 @@ const path_1 = tslib_1.__importDefault(require("path"));
6
6
  const log_1 = tslib_1.__importDefault(require("../../log"));
7
7
  const local_1 = require("../local");
8
8
  const vcs_1 = require("../vcs");
9
+ let hasWarnedAboutEasProjectRoot = false;
9
10
  class NoVcsClient extends vcs_1.Client {
10
11
  cwdOverride;
11
12
  constructor(options = {}) {
@@ -26,9 +27,12 @@ class NoVcsClient extends vcs_1.Client {
26
27
  })).stdout.trim();
27
28
  }
28
29
  catch (err) {
29
- log_1.default.warn(`Failed to get Git root path with \`git rev-parse --show-toplevel\`.`, err);
30
- log_1.default.warn('Falling back to using current working directory as project root.');
31
- log_1.default.warn('You can set `EAS_PROJECT_ROOT` environment variable to let eas-cli know where your project is located.');
30
+ if (!hasWarnedAboutEasProjectRoot) {
31
+ log_1.default.warn(`Failed to get Git root path with \`git rev-parse --show-toplevel\`.`, err);
32
+ log_1.default.warn('Falling back to using current working directory as project root.');
33
+ log_1.default.warn('You can set `EAS_PROJECT_ROOT` environment variable to let eas-cli know where your project is located.');
34
+ hasWarnedAboutEasProjectRoot = true;
35
+ }
32
36
  }
33
37
  return path_1.default.resolve(process.cwd(), process.env.EAS_PROJECT_ROOT ?? '.');
34
38
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "15.0.15",
2
+ "version": "16.0.0",
3
3
  "commands": {
4
4
  "analytics": {
5
5
  "id": "analytics",
@@ -2845,6 +2845,55 @@
2845
2845
  "vcsClient": {}
2846
2846
  }
2847
2847
  },
2848
+ "fingerprint:generate": {
2849
+ "id": "fingerprint:generate",
2850
+ "description": "generate fingerprints from the current project",
2851
+ "strict": false,
2852
+ "pluginName": "eas-cli",
2853
+ "pluginAlias": "eas-cli",
2854
+ "pluginType": "core",
2855
+ "hidden": true,
2856
+ "aliases": [],
2857
+ "examples": [
2858
+ "$ eas fingerprint:generate",
2859
+ "$ eas fingerprint:generate --json --non-interactive -p android"
2860
+ ],
2861
+ "flags": {
2862
+ "platform": {
2863
+ "name": "platform",
2864
+ "type": "option",
2865
+ "char": "p",
2866
+ "helpValue": "(android|ios)",
2867
+ "multiple": false,
2868
+ "options": [
2869
+ "android",
2870
+ "ios"
2871
+ ]
2872
+ },
2873
+ "json": {
2874
+ "name": "json",
2875
+ "type": "boolean",
2876
+ "description": "Enable JSON output, non-JSON messages will be printed to stderr.",
2877
+ "allowNo": false,
2878
+ "dependsOn": [
2879
+ "non-interactive"
2880
+ ]
2881
+ },
2882
+ "non-interactive": {
2883
+ "name": "non-interactive",
2884
+ "type": "boolean",
2885
+ "description": "Run the command in non-interactive mode.",
2886
+ "allowNo": false
2887
+ }
2888
+ },
2889
+ "args": {},
2890
+ "contextDefinition": {
2891
+ "projectId": {},
2892
+ "loggedIn": {},
2893
+ "privateProjectConfig": {},
2894
+ "vcsClient": {}
2895
+ }
2896
+ },
2848
2897
  "metadata:lint": {
2849
2898
  "id": "metadata:lint",
2850
2899
  "description": "validate the local store configuration",