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.
- package/README.md +74 -74
- package/build/ApiV2Error.d.ts +2 -0
- package/build/ApiV2Error.js +2 -0
- package/build/build/build.js +2 -2
- package/build/commands/build/dev.js +2 -2
- package/build/commands/fingerprint/compare.js +10 -88
- package/build/commands/fingerprint/generate.d.ts +21 -0
- package/build/commands/fingerprint/generate.js +81 -0
- package/build/{utils/fingerprintCli.d.ts → fingerprint/cli.d.ts} +1 -1
- package/build/{utils/fingerprintCli.js → fingerprint/cli.js} +1 -1
- package/build/fingerprint/utils.d.ts +9 -0
- package/build/fingerprint/utils.js +93 -0
- package/build/project/publish.js +2 -2
- package/build/run/utils.js +1 -1
- package/build/vcs/clients/git.js +7 -4
- package/build/vcs/clients/noVcs.js +7 -3
- package/oclif.manifest.json +50 -1
- package/package.json +3 -3
- /package/build/{utils/fingerprintDiff.d.ts → fingerprint/diff.d.ts} +0 -0
- /package/build/{utils/fingerprintDiff.js → fingerprint/diff.js} +0 -0
- /package/build/{utils/fingerprint.d.ts → fingerprint/types.d.ts} +0 -0
- /package/build/{utils/fingerprint.js → fingerprint/types.js} +0 -0
package/build/ApiV2Error.d.ts
CHANGED
|
@@ -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
|
}
|
package/build/ApiV2Error.js
CHANGED
|
@@ -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;
|
package/build/build/build.js
CHANGED
|
@@ -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,
|
|
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,
|
|
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
|
|
15
|
-
const
|
|
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,
|
|
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
|
|
282
|
-
|
|
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,
|
|
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;
|
|
@@ -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;
|
package/build/project/publish.js
CHANGED
|
@@ -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,
|
|
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,
|
package/build/run/utils.js
CHANGED
|
@@ -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()
|
|
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 &&
|
package/build/vcs/clients/git.js
CHANGED
|
@@ -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
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
}
|
package/oclif.manifest.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "
|
|
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",
|