eas-cli 14.7.1 → 15.0.1

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.
@@ -7162,6 +7162,7 @@ export type WorkflowRun = ActivityTimelineProjectActivity & {
7162
7162
  requestedGitRef?: Maybe<Scalars['String']['output']>;
7163
7163
  retriedWorkflowRun?: Maybe<WorkflowRun>;
7164
7164
  retries: Array<WorkflowRun>;
7165
+ sourceExpiresAt?: Maybe<Scalars['DateTime']['output']>;
7165
7166
  status: WorkflowRunStatus;
7166
7167
  triggerEventType: WorkflowRunTriggerEventType;
7167
7168
  updatedAt: Scalars['DateTime']['output'];
@@ -11150,6 +11151,12 @@ export type CreateAndroidBuildMutation = {
11150
11151
  name: string;
11151
11152
  slug: string;
11152
11153
  };
11154
+ metrics?: {
11155
+ __typename?: 'BuildMetrics';
11156
+ buildWaitTime?: number | null;
11157
+ buildQueueTime?: number | null;
11158
+ buildDuration?: number | null;
11159
+ } | null;
11153
11160
  };
11154
11161
  deprecationInfo?: {
11155
11162
  __typename?: 'EASBuildDeprecationInfo';
@@ -11238,6 +11245,12 @@ export type CreateIosBuildMutation = {
11238
11245
  name: string;
11239
11246
  slug: string;
11240
11247
  };
11248
+ metrics?: {
11249
+ __typename?: 'BuildMetrics';
11250
+ buildWaitTime?: number | null;
11251
+ buildQueueTime?: number | null;
11252
+ buildDuration?: number | null;
11253
+ } | null;
11241
11254
  };
11242
11255
  deprecationInfo?: {
11243
11256
  __typename?: 'EASBuildDeprecationInfo';
@@ -11322,6 +11335,12 @@ export type UpdateBuildMetadataMutation = {
11322
11335
  name: string;
11323
11336
  slug: string;
11324
11337
  };
11338
+ metrics?: {
11339
+ __typename?: 'BuildMetrics';
11340
+ buildWaitTime?: number | null;
11341
+ buildQueueTime?: number | null;
11342
+ buildDuration?: number | null;
11343
+ } | null;
11325
11344
  };
11326
11345
  };
11327
11346
  };
@@ -11400,6 +11419,12 @@ export type RetryIosBuildMutation = {
11400
11419
  name: string;
11401
11420
  slug: string;
11402
11421
  };
11422
+ metrics?: {
11423
+ __typename?: 'BuildMetrics';
11424
+ buildWaitTime?: number | null;
11425
+ buildQueueTime?: number | null;
11426
+ buildDuration?: number | null;
11427
+ } | null;
11403
11428
  };
11404
11429
  };
11405
11430
  };
@@ -11705,6 +11730,7 @@ export type UpdatePublishMutation = {
11705
11730
  __typename?: 'Fingerprint';
11706
11731
  id: string;
11707
11732
  hash: string;
11733
+ debugInfoUrl?: string | null;
11708
11734
  source?: {
11709
11735
  __typename?: 'FingerprintSource';
11710
11736
  type: FingerprintSourceType;
@@ -11790,6 +11816,7 @@ export type SetRolloutPercentageMutation = {
11790
11816
  __typename?: 'Fingerprint';
11791
11817
  id: string;
11792
11818
  hash: string;
11819
+ debugInfoUrl?: string | null;
11793
11820
  source?: {
11794
11821
  __typename?: 'FingerprintSource';
11795
11822
  type: FingerprintSourceType;
@@ -12260,6 +12287,7 @@ export type BranchesByAppQuery = {
12260
12287
  __typename?: 'Fingerprint';
12261
12288
  id: string;
12262
12289
  hash: string;
12290
+ debugInfoUrl?: string | null;
12263
12291
  source?: {
12264
12292
  __typename?: 'FingerprintSource';
12265
12293
  type: FingerprintSourceType;
@@ -12373,6 +12401,7 @@ export type ViewBranchesOnUpdateChannelQuery = {
12373
12401
  __typename?: 'Fingerprint';
12374
12402
  id: string;
12375
12403
  hash: string;
12404
+ debugInfoUrl?: string | null;
12376
12405
  source?: {
12377
12406
  __typename?: 'FingerprintSource';
12378
12407
  type: FingerprintSourceType;
@@ -12460,6 +12489,12 @@ export type BuildsByIdQuery = {
12460
12489
  name: string;
12461
12490
  slug: string;
12462
12491
  };
12492
+ metrics?: {
12493
+ __typename?: 'BuildMetrics';
12494
+ buildWaitTime?: number | null;
12495
+ buildQueueTime?: number | null;
12496
+ buildDuration?: number | null;
12497
+ } | null;
12463
12498
  };
12464
12499
  };
12465
12500
  };
@@ -12572,6 +12607,12 @@ export type BuildsWithSubmissionsByIdQuery = {
12572
12607
  name: string;
12573
12608
  slug: string;
12574
12609
  };
12610
+ metrics?: {
12611
+ __typename?: 'BuildMetrics';
12612
+ buildWaitTime?: number | null;
12613
+ buildQueueTime?: number | null;
12614
+ buildDuration?: number | null;
12615
+ } | null;
12575
12616
  };
12576
12617
  };
12577
12618
  };
@@ -12677,6 +12718,12 @@ export type BuildsWithFingerprintByIdQuery = {
12677
12718
  name: string;
12678
12719
  slug: string;
12679
12720
  };
12721
+ metrics?: {
12722
+ __typename?: 'BuildMetrics';
12723
+ buildWaitTime?: number | null;
12724
+ buildQueueTime?: number | null;
12725
+ buildDuration?: number | null;
12726
+ } | null;
12680
12727
  };
12681
12728
  };
12682
12729
  };
@@ -12760,6 +12807,12 @@ export type ViewBuildsOnAppQuery = {
12760
12807
  name: string;
12761
12808
  slug: string;
12762
12809
  };
12810
+ metrics?: {
12811
+ __typename?: 'BuildMetrics';
12812
+ buildWaitTime?: number | null;
12813
+ buildQueueTime?: number | null;
12814
+ buildDuration?: number | null;
12815
+ } | null;
12763
12816
  }>;
12764
12817
  };
12765
12818
  };
@@ -12833,6 +12886,7 @@ export type ViewUpdateChannelOnAppQuery = {
12833
12886
  __typename?: 'Fingerprint';
12834
12887
  id: string;
12835
12888
  hash: string;
12889
+ debugInfoUrl?: string | null;
12836
12890
  source?: {
12837
12891
  __typename?: 'FingerprintSource';
12838
12892
  type: FingerprintSourceType;
@@ -12915,6 +12969,7 @@ export type ViewUpdateChannelsOnAppQuery = {
12915
12969
  __typename?: 'Fingerprint';
12916
12970
  id: string;
12917
12971
  hash: string;
12972
+ debugInfoUrl?: string | null;
12918
12973
  source?: {
12919
12974
  __typename?: 'FingerprintSource';
12920
12975
  type: FingerprintSourceType;
@@ -13434,6 +13489,7 @@ export type ViewUpdatesByGroupQuery = {
13434
13489
  __typename?: 'Fingerprint';
13435
13490
  id: string;
13436
13491
  hash: string;
13492
+ debugInfoUrl?: string | null;
13437
13493
  source?: {
13438
13494
  __typename?: 'FingerprintSource';
13439
13495
  type: FingerprintSourceType;
@@ -13505,6 +13561,7 @@ export type ViewUpdateGroupsOnBranchQuery = {
13505
13561
  __typename?: 'Fingerprint';
13506
13562
  id: string;
13507
13563
  hash: string;
13564
+ debugInfoUrl?: string | null;
13508
13565
  source?: {
13509
13566
  __typename?: 'FingerprintSource';
13510
13567
  type: FingerprintSourceType;
@@ -13575,6 +13632,7 @@ export type ViewUpdateGroupsOnAppQuery = {
13575
13632
  __typename?: 'Fingerprint';
13576
13633
  id: string;
13577
13634
  hash: string;
13635
+ debugInfoUrl?: string | null;
13578
13636
  source?: {
13579
13637
  __typename?: 'FingerprintSource';
13580
13638
  type: FingerprintSourceType;
@@ -13586,6 +13644,69 @@ export type ViewUpdateGroupsOnAppQuery = {
13586
13644
  };
13587
13645
  };
13588
13646
  };
13647
+ export type UpdateByIdQueryVariables = Exact<{
13648
+ updateId: Scalars['ID']['input'];
13649
+ }>;
13650
+ export type UpdateByIdQuery = {
13651
+ __typename?: 'RootQuery';
13652
+ updates: {
13653
+ __typename?: 'UpdateQuery';
13654
+ byId: {
13655
+ __typename?: 'Update';
13656
+ id: string;
13657
+ group: string;
13658
+ message?: string | null;
13659
+ createdAt: any;
13660
+ runtimeVersion: string;
13661
+ platform: string;
13662
+ manifestFragment: string;
13663
+ isRollBackToEmbedded: boolean;
13664
+ manifestPermalink: string;
13665
+ gitCommitHash?: string | null;
13666
+ rolloutPercentage?: number | null;
13667
+ actor?: {
13668
+ __typename: 'Robot';
13669
+ firstName?: string | null;
13670
+ id: string;
13671
+ } | {
13672
+ __typename: 'SSOUser';
13673
+ username: string;
13674
+ id: string;
13675
+ } | {
13676
+ __typename: 'User';
13677
+ username: string;
13678
+ id: string;
13679
+ } | null;
13680
+ branch: {
13681
+ __typename?: 'UpdateBranch';
13682
+ id: string;
13683
+ name: string;
13684
+ };
13685
+ codeSigningInfo?: {
13686
+ __typename?: 'CodeSigningInfo';
13687
+ keyid: string;
13688
+ sig: string;
13689
+ alg: string;
13690
+ } | null;
13691
+ rolloutControlUpdate?: {
13692
+ __typename?: 'Update';
13693
+ id: string;
13694
+ } | null;
13695
+ fingerprint?: {
13696
+ __typename?: 'Fingerprint';
13697
+ id: string;
13698
+ hash: string;
13699
+ debugInfoUrl?: string | null;
13700
+ source?: {
13701
+ __typename?: 'FingerprintSource';
13702
+ type: FingerprintSourceType;
13703
+ bucketKey: string;
13704
+ isDebugFingerprint?: boolean | null;
13705
+ } | null;
13706
+ } | null;
13707
+ };
13708
+ };
13709
+ };
13589
13710
  export type CurrentUserQueryVariables = Exact<{
13590
13711
  [key: string]: never;
13591
13712
  }>;
@@ -13953,6 +14074,12 @@ export type BuildFragment = {
13953
14074
  name: string;
13954
14075
  slug: string;
13955
14076
  };
14077
+ metrics?: {
14078
+ __typename?: 'BuildMetrics';
14079
+ buildWaitTime?: number | null;
14080
+ buildQueueTime?: number | null;
14081
+ buildDuration?: number | null;
14082
+ } | null;
13956
14083
  };
13957
14084
  export type BuildWithSubmissionsFragment = {
13958
14085
  __typename?: 'Build';
@@ -14056,6 +14183,12 @@ export type BuildWithSubmissionsFragment = {
14056
14183
  name: string;
14057
14184
  slug: string;
14058
14185
  };
14186
+ metrics?: {
14187
+ __typename?: 'BuildMetrics';
14188
+ buildWaitTime?: number | null;
14189
+ buildQueueTime?: number | null;
14190
+ buildDuration?: number | null;
14191
+ } | null;
14059
14192
  };
14060
14193
  export type BuildWithFingerprintFragment = {
14061
14194
  __typename?: 'Build';
@@ -14152,6 +14285,12 @@ export type BuildWithFingerprintFragment = {
14152
14285
  name: string;
14153
14286
  slug: string;
14154
14287
  };
14288
+ metrics?: {
14289
+ __typename?: 'BuildMetrics';
14290
+ buildWaitTime?: number | null;
14291
+ buildQueueTime?: number | null;
14292
+ buildDuration?: number | null;
14293
+ } | null;
14155
14294
  };
14156
14295
  export type EnvironmentSecretFragment = {
14157
14296
  __typename?: 'EnvironmentSecret';
@@ -14311,6 +14450,7 @@ export type UpdateFragment = {
14311
14450
  __typename?: 'Fingerprint';
14312
14451
  id: string;
14313
14452
  hash: string;
14453
+ debugInfoUrl?: string | null;
14314
14454
  source?: {
14315
14455
  __typename?: 'FingerprintSource';
14316
14456
  type: FingerprintSourceType;
@@ -14368,6 +14508,7 @@ export type UpdateBranchFragment = {
14368
14508
  __typename?: 'Fingerprint';
14369
14509
  id: string;
14370
14510
  hash: string;
14511
+ debugInfoUrl?: string | null;
14371
14512
  source?: {
14372
14513
  __typename?: 'FingerprintSource';
14373
14514
  type: FingerprintSourceType;
@@ -1,7 +1,8 @@
1
1
  import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
2
- import { UpdateFragment, ViewUpdateGroupsOnAppQueryVariables, ViewUpdateGroupsOnBranchQueryVariables, ViewUpdatesByGroupQueryVariables } from '../generated';
2
+ import { UpdateByIdQueryVariables, UpdateFragment, ViewUpdateGroupsOnAppQueryVariables, ViewUpdateGroupsOnBranchQueryVariables, ViewUpdatesByGroupQueryVariables } from '../generated';
3
3
  export declare const UpdateQuery: {
4
4
  viewUpdateGroupAsync(graphqlClient: ExpoGraphqlClient, { groupId }: ViewUpdatesByGroupQueryVariables): Promise<UpdateFragment[]>;
5
5
  viewUpdateGroupsOnBranchAsync(graphqlClient: ExpoGraphqlClient, { limit, offset, appId, branchName, filter }: ViewUpdateGroupsOnBranchQueryVariables): Promise<UpdateFragment[][]>;
6
6
  viewUpdateGroupsOnAppAsync(graphqlClient: ExpoGraphqlClient, { limit, offset, appId, filter }: ViewUpdateGroupsOnAppQueryVariables): Promise<UpdateFragment[][]>;
7
+ viewByUpdateAsync(graphqlClient: ExpoGraphqlClient, { updateId }: UpdateByIdQueryVariables): Promise<UpdateFragment>;
7
8
  };
@@ -96,4 +96,20 @@ exports.UpdateQuery = {
96
96
  }
97
97
  return response.app.byId.updateGroups;
98
98
  },
99
+ async viewByUpdateAsync(graphqlClient, { updateId }) {
100
+ const data = await (0, client_1.withErrorHandlingAsync)(graphqlClient
101
+ .query((0, graphql_tag_1.default) `
102
+ query UpdateByIdQuery($updateId: ID!) {
103
+ updates {
104
+ byId(updateId: $updateId) {
105
+ id
106
+ ...UpdateFragment
107
+ }
108
+ }
109
+ }
110
+ ${(0, graphql_1.print)(Update_1.UpdateFragmentNode)}
111
+ `, { updateId }, { additionalTypenames: ['Update'] })
112
+ .toPromise());
113
+ return data.updates.byId;
114
+ },
99
115
  };
@@ -59,6 +59,11 @@ exports.BuildFragmentNode = (0, graphql_tag_1.default) `
59
59
  completedAt
60
60
  expirationDate
61
61
  isForIosSimulator
62
+ metrics {
63
+ buildWaitTime
64
+ buildQueueTime
65
+ buildDuration
66
+ }
62
67
  }
63
68
  `;
64
69
  exports.BuildFragmentWithSubmissionsNode = (0, graphql_tag_1.default) `
@@ -41,6 +41,7 @@ exports.UpdateFragmentNode = (0, graphql_tag_1.default) `
41
41
  fingerprint {
42
42
  id
43
43
  hash
44
+ debugInfoUrl
44
45
  source {
45
46
  type
46
47
  bucketKey
@@ -6,3 +6,4 @@ export interface RunArchiveFlags {
6
6
  url?: string;
7
7
  }
8
8
  export declare function runAsync(simulatorBuildPath: string, selectedPlatform: AppPlatform): Promise<void>;
9
+ export declare function getEasBuildRunCachedAppPath(projectId: string, buildId: string, platform: AppPlatform): string;
package/build/run/run.js CHANGED
@@ -1,9 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.runAsync = void 0;
3
+ exports.getEasBuildRunCachedAppPath = exports.runAsync = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const path_1 = tslib_1.__importDefault(require("path"));
4
6
  const run_1 = require("./android/run");
5
7
  const run_2 = require("./ios/run");
6
8
  const generated_1 = require("../graphql/generated");
9
+ const paths_1 = require("../utils/paths");
7
10
  async function runAsync(simulatorBuildPath, selectedPlatform) {
8
11
  if (selectedPlatform === generated_1.AppPlatform.Ios) {
9
12
  await (0, run_2.runAppOnIosSimulatorAsync)(simulatorBuildPath);
@@ -13,3 +16,7 @@ async function runAsync(simulatorBuildPath, selectedPlatform) {
13
16
  }
14
17
  }
15
18
  exports.runAsync = runAsync;
19
+ function getEasBuildRunCachedAppPath(projectId, buildId, platform) {
20
+ return path_1.default.join((0, paths_1.getEasBuildRunCacheDirectoryPath)(), `${projectId}_${buildId}.${platform === generated_1.AppPlatform.Ios ? 'app' : 'apk'}`);
21
+ }
22
+ exports.getEasBuildRunCachedAppPath = getEasBuildRunCachedAppPath;
@@ -1,17 +1,21 @@
1
1
  import { Client } from '../vcs';
2
2
  export default class GitClient extends Client {
3
3
  private readonly maybeCwdOverride?;
4
- constructor(maybeCwdOverride?: string | undefined);
4
+ requireCommit: boolean;
5
+ constructor(options: {
6
+ maybeCwdOverride?: string;
7
+ requireCommit: boolean;
8
+ });
5
9
  ensureRepoExistsAsync(): Promise<void>;
6
10
  commitAsync({ commitMessage, commitAllFiles, nonInteractive, }: {
7
11
  commitMessage: string;
8
12
  commitAllFiles?: boolean;
9
13
  nonInteractive: boolean;
10
14
  }): Promise<void>;
11
- isCommitRequiredAsync(): Promise<boolean>;
12
15
  showChangedFilesAsync(): Promise<void>;
13
16
  hasUncommittedChangesAsync(): Promise<boolean>;
14
17
  getRootPathAsync(): Promise<string>;
18
+ isCommitRequiredAsync(): Promise<boolean>;
15
19
  makeShallowCopyAsync(destinationPath: string): Promise<void>;
16
20
  getCommitHashAsync(): Promise<string | undefined>;
17
21
  trackFileAsync(file: string): Promise<void>;
@@ -6,17 +6,21 @@ const PackageManagerUtils = tslib_1.__importStar(require("@expo/package-manager"
6
6
  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
+ const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
9
10
  const path_1 = tslib_1.__importDefault(require("path"));
10
11
  const log_1 = tslib_1.__importStar(require("../../log"));
11
12
  const ora_1 = require("../../ora");
12
13
  const prompts_1 = require("../../prompts");
13
14
  const git_1 = require("../git");
15
+ const local_1 = require("../local");
14
16
  const vcs_1 = require("../vcs");
15
17
  class GitClient extends vcs_1.Client {
16
18
  maybeCwdOverride;
17
- constructor(maybeCwdOverride) {
19
+ requireCommit;
20
+ constructor(options) {
18
21
  super();
19
- this.maybeCwdOverride = maybeCwdOverride;
22
+ this.maybeCwdOverride = options.maybeCwdOverride;
23
+ this.requireCommit = options.requireCommit;
20
24
  }
21
25
  async ensureRepoExistsAsync() {
22
26
  try {
@@ -84,9 +88,6 @@ class GitClient extends vcs_1.Client {
84
88
  throw err;
85
89
  }
86
90
  }
87
- async isCommitRequiredAsync() {
88
- return await this.hasUncommittedChangesAsync();
89
- }
90
91
  async showChangedFilesAsync() {
91
92
  const gitStatusOutput = await (0, git_1.gitStatusAsync)({
92
93
  showUntracked: true,
@@ -103,44 +104,61 @@ class GitClient extends vcs_1.Client {
103
104
  cwd: this.maybeCwdOverride,
104
105
  })).stdout.trim();
105
106
  }
107
+ async isCommitRequiredAsync() {
108
+ if (!this.requireCommit) {
109
+ return false;
110
+ }
111
+ return await this.hasUncommittedChangesAsync();
112
+ }
106
113
  async makeShallowCopyAsync(destinationPath) {
107
- if (await this.hasUncommittedChangesAsync()) {
114
+ if (await this.isCommitRequiredAsync()) {
108
115
  // it should already be checked before this function is called, but in case it wasn't
109
116
  // we want to ensure that any changes were introduced by call to `setGitCaseSensitivityAsync`
110
117
  throw new Error('You have some uncommitted changes in your repository.');
111
118
  }
119
+ const rootPath = await this.getRootPathAsync();
112
120
  let gitRepoUri;
113
121
  if (process.platform === 'win32') {
114
122
  // getRootDirectoryAsync() will return C:/path/to/repo on Windows and path
115
123
  // prefix should be file:///
116
- gitRepoUri = `file:///${await this.getRootPathAsync()}`;
124
+ gitRepoUri = `file:///${rootPath}`;
117
125
  }
118
126
  else {
119
127
  // getRootDirectoryAsync() will /path/to/repo, and path prefix should be
120
128
  // file:/// so only file:// needs to be prepended
121
- gitRepoUri = `file://${await this.getRootPathAsync()}`;
129
+ gitRepoUri = `file://${rootPath}`;
122
130
  }
123
- const isCaseSensitive = await isGitCaseSensitiveAsync(this.maybeCwdOverride);
124
- await setGitCaseSensitivityAsync(true, this.maybeCwdOverride);
131
+ await assertEnablingGitCaseSensitivityDoesNotCauseNewUncommittedChangesAsync(rootPath);
132
+ const isCaseSensitive = await isGitCaseSensitiveAsync(rootPath);
125
133
  try {
126
- if (await this.hasUncommittedChangesAsync()) {
127
- log_1.default.error('Detected inconsistent filename casing between your local filesystem and git.');
128
- log_1.default.error('This will likely cause your build to fail. Impacted files:');
129
- await (0, spawn_async_1.default)('git', ['status', '--short'], {
130
- stdio: 'inherit',
131
- cwd: this.maybeCwdOverride,
132
- });
133
- log_1.default.newLine();
134
- log_1.default.error(`Error: Resolve filename casing inconsistencies before proceeding. ${(0, log_1.learnMore)('https://expo.fyi/macos-ignorecase')}`);
135
- throw new Error('You have some uncommitted changes in your repository.');
134
+ await setGitCaseSensitivityAsync(true, rootPath);
135
+ await (0, spawn_async_1.default)('git', ['clone', '--no-hardlinks', '--depth', '1', gitRepoUri, destinationPath], { cwd: rootPath });
136
+ const sourceEasignorePath = path_1.default.join(rootPath, local_1.EASIGNORE_FILENAME);
137
+ if (await fs_extra_1.default.exists(sourceEasignorePath)) {
138
+ const cachedFilesWeShouldHaveIgnored = (await (0, spawn_async_1.default)('git', [
139
+ 'ls-files',
140
+ '--exclude-from',
141
+ sourceEasignorePath,
142
+ // `--ignored --cached` makes git print files that should be
143
+ // ignored by rules from `--exclude-from`, but instead are currently cached.
144
+ '--ignored',
145
+ '--cached',
146
+ // separates file names with null characters
147
+ '-z',
148
+ ], { cwd: destinationPath })).stdout
149
+ .split('\0')
150
+ // ls-files' output is terminated by a null character
151
+ .filter(file => file !== '');
152
+ await Promise.all(cachedFilesWeShouldHaveIgnored.map(file => fs_extra_1.default.rm(path_1.default.join(destinationPath, file))));
136
153
  }
137
- await (0, spawn_async_1.default)('git', ['clone', '--no-hardlinks', '--depth', '1', gitRepoUri, destinationPath], {
138
- cwd: this.maybeCwdOverride,
139
- });
140
154
  }
141
155
  finally {
142
- await setGitCaseSensitivityAsync(isCaseSensitive, this.maybeCwdOverride);
156
+ await setGitCaseSensitivityAsync(isCaseSensitive, rootPath);
143
157
  }
158
+ // After we create the shallow Git copy, we copy the files
159
+ // again. This way we include the changed and untracked files
160
+ // (`git clone` only copies the committed changes).
161
+ await (0, local_1.makeShallowCopyAsync)(rootPath, destinationPath);
144
162
  }
145
163
  async getCommitHashAsync() {
146
164
  try {
@@ -192,10 +210,16 @@ class GitClient extends vcs_1.Client {
192
210
  !trackedFiles.includes(pathWithoutLeadingDot));
193
211
  }
194
212
  async isFileIgnoredAsync(filePath) {
213
+ const rootPath = await this.getRootPathAsync();
214
+ const easIgnorePath = path_1.default.join(rootPath, local_1.EASIGNORE_FILENAME);
215
+ if (await fs_extra_1.default.exists(easIgnorePath)) {
216
+ const ignore = new local_1.Ignore(rootPath);
217
+ const wouldNotBeCopiedToClone = ignore.ignores(filePath);
218
+ const wouldBeDeletedFromClone = (await (0, spawn_async_1.default)('git', ['ls-files', '--exclude-from', easIgnorePath, '--ignored', '--cached', filePath], { cwd: rootPath })).stdout.trim() !== '';
219
+ return wouldNotBeCopiedToClone && wouldBeDeletedFromClone;
220
+ }
195
221
  try {
196
- await (0, spawn_async_1.default)('git', ['check-ignore', '-q', filePath], {
197
- cwd: this.maybeCwdOverride ?? path_1.default.normalize(await this.getRootPathAsync()),
198
- });
222
+ await (0, spawn_async_1.default)('git', ['check-ignore', '-q', filePath], { cwd: rootPath });
199
223
  return true;
200
224
  }
201
225
  catch {
@@ -318,3 +342,39 @@ async function setGitCaseSensitivityAsync(enable, cwd) {
318
342
  });
319
343
  }
320
344
  }
345
+ async function assertEnablingGitCaseSensitivityDoesNotCauseNewUncommittedChangesAsync(cwd) {
346
+ // Remember uncommited changes before case sensitivity change
347
+ // for later comparison so we log to the user only the files
348
+ // that were marked as changed after the case sensitivity change.
349
+ const uncommittedChangesBeforeCaseSensitivityChange = await (0, git_1.gitStatusAsync)({
350
+ showUntracked: true,
351
+ cwd,
352
+ });
353
+ const isCaseSensitive = await isGitCaseSensitiveAsync(cwd);
354
+ await setGitCaseSensitivityAsync(true, cwd);
355
+ try {
356
+ const uncommitedChangesAfterCaseSensitivityChange = await (0, git_1.gitStatusAsync)({
357
+ showUntracked: true,
358
+ cwd,
359
+ });
360
+ if (uncommitedChangesAfterCaseSensitivityChange !== uncommittedChangesBeforeCaseSensitivityChange) {
361
+ const baseUncommitedChangesSet = new Set(uncommittedChangesBeforeCaseSensitivityChange.split('\n'));
362
+ const errorMessage = [
363
+ 'Detected inconsistent filename casing between your local filesystem and git.',
364
+ 'This will likely cause your job to fail. Impacted files:',
365
+ ...uncommitedChangesAfterCaseSensitivityChange.split('\n').flatMap(changedFile => {
366
+ // This file was changed before the case sensitivity change too.
367
+ if (baseUncommitedChangesSet.has(changedFile)) {
368
+ return [];
369
+ }
370
+ return [changedFile];
371
+ }),
372
+ `Resolve filename casing inconsistencies before proceeding. ${(0, log_1.learnMore)('https://expo.fyi/macos-ignorecase')}`,
373
+ ];
374
+ throw new Error(errorMessage.join('\n'));
375
+ }
376
+ }
377
+ finally {
378
+ await setGitCaseSensitivityAsync(isCaseSensitive, cwd);
379
+ }
380
+ }
@@ -4,23 +4,23 @@ exports.resolveVcsClient = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const chalk_1 = tslib_1.__importDefault(require("chalk"));
6
6
  const git_1 = tslib_1.__importDefault(require("./clients/git"));
7
- const gitNoCommit_1 = tslib_1.__importDefault(require("./clients/gitNoCommit"));
8
7
  const noVcs_1 = tslib_1.__importDefault(require("./clients/noVcs"));
9
8
  const NO_VCS_WARNING = `Using EAS CLI without version control system is not recommended, use this mode only if you know what you are doing.`;
9
+ let wasNoVcsWarningPrinted = false;
10
10
  function resolveVcsClient(requireCommit = false) {
11
11
  if (process.env.EAS_NO_VCS) {
12
12
  if (process.env.NODE_ENV !== 'test') {
13
- // This log might be printed before cli arguments are evaluated,
14
- // so it needs to go to stderr in case command is run in JSON
15
- // only mode.
16
- // eslint-disable-next-line no-console
17
- console.error(chalk_1.default.yellow(NO_VCS_WARNING));
13
+ if (!wasNoVcsWarningPrinted) {
14
+ // This log might be printed before cli arguments are evaluated,
15
+ // so it needs to go to stderr in case command is run in JSON
16
+ // only mode.
17
+ // eslint-disable-next-line no-console
18
+ console.error(chalk_1.default.yellow(NO_VCS_WARNING));
19
+ wasNoVcsWarningPrinted = true;
20
+ }
18
21
  }
19
22
  return new noVcs_1.default();
20
23
  }
21
- if (requireCommit) {
22
- return new git_1.default();
23
- }
24
- return new gitNoCommit_1.default();
24
+ return new git_1.default({ requireCommit });
25
25
  }
26
26
  exports.resolveVcsClient = resolveVcsClient;
@@ -1,3 +1,4 @@
1
+ export declare const EASIGNORE_FILENAME = ".easignore";
1
2
  export declare function getRootPath(): string;
2
3
  /**
3
4
  * Ignore wraps the 'ignore' package to support multiple .gitignore files
@@ -1,12 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.makeShallowCopyAsync = exports.Ignore = exports.getRootPath = void 0;
3
+ exports.makeShallowCopyAsync = exports.Ignore = exports.getRootPath = exports.EASIGNORE_FILENAME = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const fast_glob_1 = tslib_1.__importDefault(require("fast-glob"));
6
6
  const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
7
7
  const ignore_1 = tslib_1.__importDefault(require("ignore"));
8
8
  const path_1 = tslib_1.__importDefault(require("path"));
9
- const EASIGNORE_FILENAME = '.easignore';
9
+ exports.EASIGNORE_FILENAME = '.easignore';
10
10
  const GITIGNORE_FILENAME = '.gitignore';
11
11
  const DEFAULT_IGNORE = `
12
12
  .git
@@ -37,7 +37,7 @@ class Ignore {
37
37
  this.rootDir = rootDir;
38
38
  }
39
39
  async initIgnoreAsync() {
40
- const easIgnorePath = path_1.default.join(this.rootDir, EASIGNORE_FILENAME);
40
+ const easIgnorePath = path_1.default.join(this.rootDir, exports.EASIGNORE_FILENAME);
41
41
  if (await fs_extra_1.default.pathExists(easIgnorePath)) {
42
42
  this.ignoreMapping = [
43
43
  ['', (0, ignore_1.default)().add(DEFAULT_IGNORE)],