eas-cli 13.2.3 → 13.4.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 +359 -162
- package/build/build/build.js +3 -3
- package/build/build/evaluateConfigWithEnvVarsAsync.js +18 -2
- package/build/build/utils/url.d.ts +1 -0
- package/build/build/utils/url.js +5 -1
- package/build/commandUtils/flags.d.ts +5 -4
- package/build/commandUtils/flags.js +6 -8
- package/build/commands/env/create.d.ts +6 -6
- package/build/commands/env/create.js +27 -28
- package/build/commands/env/delete.d.ts +5 -5
- package/build/commands/env/delete.js +15 -13
- package/build/commands/env/exec.d.ts +0 -1
- package/build/commands/env/exec.js +1 -2
- package/build/commands/env/get.d.ts +5 -5
- package/build/commands/env/get.js +16 -13
- package/build/commands/env/link.d.ts +1 -1
- package/build/commands/env/link.js +12 -13
- package/build/commands/env/list.d.ts +5 -5
- package/build/commands/env/list.js +14 -12
- package/build/commands/env/pull.d.ts +1 -2
- package/build/commands/env/pull.js +8 -9
- package/build/commands/env/push.d.ts +1 -2
- package/build/commands/env/push.js +9 -10
- package/build/commands/env/unlink.d.ts +1 -1
- package/build/commands/env/unlink.js +11 -10
- package/build/commands/env/update.d.ts +6 -6
- package/build/commands/env/update.js +18 -15
- package/build/commands/secret/create.d.ts +1 -0
- package/build/commands/secret/create.js +3 -0
- package/build/commands/secret/delete.d.ts +1 -0
- package/build/commands/secret/delete.js +3 -0
- package/build/commands/secret/list.d.ts +1 -0
- package/build/commands/secret/list.js +3 -0
- package/build/commands/secret/push.d.ts +1 -0
- package/build/commands/secret/push.js +3 -0
- package/build/commands/update/index.js +19 -2
- package/build/commands/workflow/create.d.ts +18 -0
- package/build/commands/workflow/create.js +100 -0
- package/build/commands/workflow/run.d.ts +0 -2
- package/build/commands/workflow/run.js +25 -6
- package/build/commands/workflow/validate.d.ts +9 -1
- package/build/commands/workflow/validate.js +47 -50
- package/build/graphql/generated.d.ts +199 -28
- package/build/graphql/generated.js +10 -1
- package/build/graphql/mutations/EnvironmentVariableMutation.d.ts +1 -0
- package/build/graphql/mutations/WorkflowRevisionMutation.d.ts +33 -0
- package/build/graphql/mutations/WorkflowRevisionMutation.js +32 -0
- package/build/graphql/types/Update.js +9 -0
- package/build/project/publish.d.ts +23 -1
- package/build/project/publish.js +71 -11
- package/build/project/resolveRuntimeVersionAsync.d.ts +2 -0
- package/build/project/resolveRuntimeVersionAsync.js +4 -0
- package/build/update/republish.js +19 -0
- package/build/utils/expodash/mapMapAsync.d.ts +1 -0
- package/build/utils/expodash/mapMapAsync.js +12 -0
- package/build/utils/fingerprintCli.d.ts +21 -3
- package/build/utils/fingerprintCli.js +62 -13
- package/build/utils/prompts.d.ts +1 -1
- package/build/utils/prompts.js +1 -1
- package/build/utils/workflowFile.d.ts +16 -0
- package/build/utils/workflowFile.js +64 -0
- package/oclif.manifest.json +84 -52
- package/package.json +10 -4
package/build/project/publish.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getRuntimeToUpdateRolloutInfoGroupMappingAsync = exports.updatePublishPlatformToAppPlatform = exports.platformDisplayNames = exports.getRuntimeToPlatformsAndFingerprintInfoMappingFromRuntimeVersionInfoObjects = exports.getRuntimeVersionInfoObjectsAsync = exports.defaultPublishPlatforms = exports.getUpdateMessageForCommandAsync = exports.getBranchNameForCommandAsync = exports.isUploadedAssetCountAboveWarningThreshold = exports.uploadAssetsAsync = exports.filterOutAssetsThatAlreadyExistAsync = exports.collectAssetsAsync = exports.getOriginalPathFromAssetMap = exports.getAssetHashFromPath = exports.loadAssetMapAsync = exports.filterCollectedAssetsByRequestedPlatforms = exports.generateEasMetadataAsync = exports.loadMetadata = exports.resolveInputDirectoryAsync = exports.buildBundlesAsync = exports.buildUnsortedUpdateInfoGroupAsync = exports.convertAssetToUpdateInfoGroupFormatAsync = exports.getStorageKeyForAssetAsync = exports.getStorageKey = exports.getBase64URLEncoding = exports.guessContentTypeFromExtension = exports.MetadataJoi = void 0;
|
|
3
|
+
exports.getRuntimeToUpdateRolloutInfoGroupMappingAsync = exports.updatePublishPlatformToAppPlatform = exports.platformDisplayNames = exports.maybeCalculateFingerprintForRuntimeVersionInfoObjectsWithoutExpoUpdatesAsync = exports.getRuntimeToPlatformsAndFingerprintInfoMappingFromRuntimeVersionInfoObjects = exports.getRuntimeVersionInfoObjectsAsync = exports.defaultPublishPlatforms = exports.getUpdateMessageForCommandAsync = exports.getBranchNameForCommandAsync = exports.isUploadedAssetCountAboveWarningThreshold = exports.uploadAssetsAsync = exports.filterOutAssetsThatAlreadyExistAsync = exports.collectAssetsAsync = exports.getOriginalPathFromAssetMap = exports.getAssetHashFromPath = exports.loadAssetMapAsync = exports.filterCollectedAssetsByRequestedPlatforms = exports.generateEasMetadataAsync = exports.loadMetadata = exports.resolveInputDirectoryAsync = exports.buildBundlesAsync = exports.buildUnsortedUpdateInfoGroupAsync = exports.convertAssetToUpdateInfoGroupFormatAsync = exports.getStorageKeyForAssetAsync = exports.getStorageKey = exports.getBase64URLEncoding = exports.guessContentTypeFromExtension = exports.MetadataJoi = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const config_plugins_1 = require("@expo/config-plugins");
|
|
6
6
|
const eas_build_job_1 = require("@expo/eas-build-job");
|
|
@@ -14,6 +14,7 @@ const mime_1 = tslib_1.__importDefault(require("mime"));
|
|
|
14
14
|
const nullthrows_1 = tslib_1.__importDefault(require("nullthrows"));
|
|
15
15
|
const path_1 = tslib_1.__importDefault(require("path"));
|
|
16
16
|
const promise_limit_1 = tslib_1.__importDefault(require("promise-limit"));
|
|
17
|
+
const maybeUploadFingerprintAsync_1 = require("./maybeUploadFingerprintAsync");
|
|
17
18
|
const projectUtils_1 = require("./projectUtils");
|
|
18
19
|
const resolveRuntimeVersionAsync_1 = require("./resolveRuntimeVersionAsync");
|
|
19
20
|
const queries_1 = require("../branch/queries");
|
|
@@ -33,7 +34,9 @@ const expoUpdatesCli_1 = require("../utils/expoUpdatesCli");
|
|
|
33
34
|
const chunk_1 = tslib_1.__importDefault(require("../utils/expodash/chunk"));
|
|
34
35
|
const filter_1 = require("../utils/expodash/filter");
|
|
35
36
|
const groupBy_1 = tslib_1.__importDefault(require("../utils/expodash/groupBy"));
|
|
37
|
+
const mapMapAsync_1 = tslib_1.__importDefault(require("../utils/expodash/mapMapAsync"));
|
|
36
38
|
const uniqBy_1 = tslib_1.__importDefault(require("../utils/expodash/uniqBy"));
|
|
39
|
+
const fingerprintCli_1 = require("../utils/fingerprintCli");
|
|
37
40
|
const fileMetadataJoi = joi_1.default.object({
|
|
38
41
|
assets: joi_1.default.array()
|
|
39
42
|
.required()
|
|
@@ -514,6 +517,7 @@ async function getRuntimeVersionInfoForPlatformAsync({ exp, platform, workflow,
|
|
|
514
517
|
return {
|
|
515
518
|
runtimeVersion: resolvedRuntimeVersion,
|
|
516
519
|
fingerprint: null,
|
|
520
|
+
fingerprintHash: null,
|
|
517
521
|
};
|
|
518
522
|
}
|
|
519
523
|
function getRuntimeToPlatformsAndFingerprintInfoMappingFromRuntimeVersionInfoObjects(runtimeVersionInfoObjects) {
|
|
@@ -523,10 +527,75 @@ function getRuntimeToPlatformsAndFingerprintInfoMappingFromRuntimeVersionInfoObj
|
|
|
523
527
|
runtimeVersion,
|
|
524
528
|
platforms: runtimeVersionInfoObjects.map(runtimeVersionInfoObject => runtimeVersionInfoObject.platform),
|
|
525
529
|
fingerprint: runtimeVersionInfoObjects.map(runtimeVersionInfoObject => runtimeVersionInfoObject.runtimeVersionInfo.fingerprint)[0] ?? null,
|
|
530
|
+
fingerprintHash: runtimeVersionInfoObjects.map(runtimeVersionInfoObject => runtimeVersionInfoObject.runtimeVersionInfo.fingerprintHash)[0] ?? null,
|
|
526
531
|
};
|
|
527
532
|
});
|
|
528
533
|
}
|
|
529
534
|
exports.getRuntimeToPlatformsAndFingerprintInfoMappingFromRuntimeVersionInfoObjects = getRuntimeToPlatformsAndFingerprintInfoMappingFromRuntimeVersionInfoObjects;
|
|
535
|
+
async function maybeCalculateFingerprintForRuntimeVersionInfoObjectsWithoutExpoUpdatesAsync({ projectDir, graphqlClient, runtimeToPlatformsAndFingerprintInfoAndFingerprintSourceMapping, workflowsByPlatform, env, }) {
|
|
536
|
+
const runtimesToComputeFingerprintsFor = runtimeToPlatformsAndFingerprintInfoAndFingerprintSourceMapping.filter(infoGroup => !infoGroup.fingerprintHash);
|
|
537
|
+
const fingerprintOptionsByRuntimeAndPlatform = new Map();
|
|
538
|
+
for (const infoGroup of runtimesToComputeFingerprintsFor) {
|
|
539
|
+
for (const platform of infoGroup.platforms) {
|
|
540
|
+
const runtimeAndPlatform = `${infoGroup.runtimeVersion}-${platform}`;
|
|
541
|
+
const options = {
|
|
542
|
+
platforms: [platform],
|
|
543
|
+
workflow: workflowsByPlatform[platform],
|
|
544
|
+
projectDir,
|
|
545
|
+
env,
|
|
546
|
+
};
|
|
547
|
+
fingerprintOptionsByRuntimeAndPlatform.set(runtimeAndPlatform, options);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
const fingerprintsByRuntimeAndPlatform = await (0, fingerprintCli_1.createFingerprintsByKeyAsync)(projectDir, fingerprintOptionsByRuntimeAndPlatform);
|
|
551
|
+
const uploadedFingerprintsByRuntimeAndPlatform = await (0, mapMapAsync_1.default)(fingerprintsByRuntimeAndPlatform, async (fingerprint) => {
|
|
552
|
+
return {
|
|
553
|
+
...fingerprint,
|
|
554
|
+
uploadedSource: (await (0, maybeUploadFingerprintAsync_1.maybeUploadFingerprintAsync)({
|
|
555
|
+
hash: fingerprint.hash,
|
|
556
|
+
fingerprint: {
|
|
557
|
+
fingerprintSources: fingerprint.sources,
|
|
558
|
+
isDebugFingerprintSource: fingerprint.isDebugSource,
|
|
559
|
+
},
|
|
560
|
+
graphqlClient,
|
|
561
|
+
})).fingerprintSource,
|
|
562
|
+
};
|
|
563
|
+
});
|
|
564
|
+
const runtimesWithComputedFingerprint = runtimesToComputeFingerprintsFor.map(runtimeInfo => {
|
|
565
|
+
const fingerprintInfoGroup = {};
|
|
566
|
+
for (const platform of runtimeInfo.platforms) {
|
|
567
|
+
const runtimeAndPlatform = `${runtimeInfo.runtimeVersion}-${platform}`;
|
|
568
|
+
const fingerprint = uploadedFingerprintsByRuntimeAndPlatform.get(runtimeAndPlatform);
|
|
569
|
+
if (fingerprint && fingerprint.uploadedSource) {
|
|
570
|
+
fingerprintInfoGroup[platform] = {
|
|
571
|
+
fingerprintHash: fingerprint.hash,
|
|
572
|
+
fingerprintSource: fingerprint.uploadedSource,
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
return {
|
|
577
|
+
...runtimeInfo,
|
|
578
|
+
fingerprintInfoGroup,
|
|
579
|
+
};
|
|
580
|
+
});
|
|
581
|
+
// These are runtimes whose fingerprint has already been computed and uploaded with EAS Update fingerprint runtime policy
|
|
582
|
+
const runtimesWithPreviouslyComputedFingerprints = runtimeToPlatformsAndFingerprintInfoAndFingerprintSourceMapping
|
|
583
|
+
.filter((infoGroup) => !!infoGroup.fingerprintHash && !!infoGroup.fingerprintSource)
|
|
584
|
+
.map(infoGroup => {
|
|
585
|
+
const platform = infoGroup.platforms[0];
|
|
586
|
+
return {
|
|
587
|
+
...infoGroup,
|
|
588
|
+
fingerprintInfoGroup: {
|
|
589
|
+
[platform]: {
|
|
590
|
+
fingerprintHash: infoGroup.fingerprintHash,
|
|
591
|
+
fingerprintSource: infoGroup.fingerprintSource,
|
|
592
|
+
},
|
|
593
|
+
},
|
|
594
|
+
};
|
|
595
|
+
});
|
|
596
|
+
return [...runtimesWithComputedFingerprint, ...runtimesWithPreviouslyComputedFingerprints];
|
|
597
|
+
}
|
|
598
|
+
exports.maybeCalculateFingerprintForRuntimeVersionInfoObjectsWithoutExpoUpdatesAsync = maybeCalculateFingerprintForRuntimeVersionInfoObjectsWithoutExpoUpdatesAsync;
|
|
530
599
|
exports.platformDisplayNames = {
|
|
531
600
|
android: 'Android',
|
|
532
601
|
ios: 'iOS',
|
|
@@ -535,18 +604,9 @@ exports.updatePublishPlatformToAppPlatform = {
|
|
|
535
604
|
android: generated_1.AppPlatform.Android,
|
|
536
605
|
ios: generated_1.AppPlatform.Ios,
|
|
537
606
|
};
|
|
538
|
-
const mapMapAsync = async function (map, mapper) {
|
|
539
|
-
const resultingMap = new Map();
|
|
540
|
-
await Promise.all(Array.from(map.keys()).map(async (k) => {
|
|
541
|
-
const initialValue = map.get(k);
|
|
542
|
-
const result = await mapper(initialValue, k);
|
|
543
|
-
resultingMap.set(k, result);
|
|
544
|
-
}));
|
|
545
|
-
return resultingMap;
|
|
546
|
-
};
|
|
547
607
|
async function getRuntimeToUpdateRolloutInfoGroupMappingAsync(graphqlClient, { appId, branchName, rolloutPercentage, runtimeToPlatformsAndFingerprintInfoMapping, }) {
|
|
548
608
|
const runtimeToPlatformsMap = new Map(runtimeToPlatformsAndFingerprintInfoMapping.map(r => [r.runtimeVersion, r.platforms]));
|
|
549
|
-
return await
|
|
609
|
+
return await (0, mapMapAsync_1.default)(runtimeToPlatformsMap, async (platforms, runtimeVersion) => {
|
|
550
610
|
return Object.fromEntries(await Promise.all(platforms.map(async (platform) => {
|
|
551
611
|
const updateIdForPlatform = await BranchQuery_1.BranchQuery.getLatestUpdateIdOnBranchAsync(graphqlClient, {
|
|
552
612
|
appId,
|
|
@@ -12,6 +12,7 @@ export declare function resolveRuntimeVersionUsingCLIAsync({ platform, workflow,
|
|
|
12
12
|
fingerprintSources: object[];
|
|
13
13
|
isDebugFingerprintSource: boolean;
|
|
14
14
|
} | null;
|
|
15
|
+
fingerprintHash: string | null;
|
|
15
16
|
}>;
|
|
16
17
|
export declare function resolveRuntimeVersionAsync({ exp, platform, workflow, projectDir, env, cwd, }: {
|
|
17
18
|
exp: ExpoConfig;
|
|
@@ -26,4 +27,5 @@ export declare function resolveRuntimeVersionAsync({ exp, platform, workflow, pr
|
|
|
26
27
|
fingerprintSources: object[];
|
|
27
28
|
isDebugFingerprintSource: boolean;
|
|
28
29
|
} | null;
|
|
30
|
+
fingerprintHash: string | null;
|
|
29
31
|
} | null>;
|
|
@@ -22,6 +22,9 @@ async function resolveRuntimeVersionUsingCLIAsync({ platform, workflow, projectD
|
|
|
22
22
|
isDebugFingerprintSource: useDebugFingerprintSource,
|
|
23
23
|
}
|
|
24
24
|
: null,
|
|
25
|
+
fingerprintHash: runtimeVersionResult.fingerprintSources
|
|
26
|
+
? runtimeVersionResult.runtimeVersion
|
|
27
|
+
: null,
|
|
25
28
|
};
|
|
26
29
|
}
|
|
27
30
|
exports.resolveRuntimeVersionUsingCLIAsync = resolveRuntimeVersionUsingCLIAsync;
|
|
@@ -32,6 +35,7 @@ async function resolveRuntimeVersionAsync({ exp, platform, workflow, projectDir,
|
|
|
32
35
|
return {
|
|
33
36
|
runtimeVersion: await config_plugins_1.Updates.getRuntimeVersionNullableAsync(projectDir, exp, platform),
|
|
34
37
|
fingerprint: null,
|
|
38
|
+
fingerprintHash: null,
|
|
35
39
|
};
|
|
36
40
|
}
|
|
37
41
|
try {
|
|
@@ -57,6 +57,25 @@ async function republishAsync({ graphqlClient, app, updatesToPublish, targetBran
|
|
|
57
57
|
}
|
|
58
58
|
: {
|
|
59
59
|
updateInfoGroup: Object.fromEntries(updatesToPublish.map(update => [update.platform, JSON.parse(update.manifestFragment)])),
|
|
60
|
+
fingerprintInfoGroup: Object.fromEntries(updatesToPublish.map(update => {
|
|
61
|
+
const fingerprint = update.fingerprint;
|
|
62
|
+
if (!fingerprint) {
|
|
63
|
+
return [update.platform, undefined];
|
|
64
|
+
}
|
|
65
|
+
return [
|
|
66
|
+
update.platform,
|
|
67
|
+
{
|
|
68
|
+
fingerprintHash: fingerprint.hash,
|
|
69
|
+
fingerprintSource: fingerprint.source
|
|
70
|
+
? {
|
|
71
|
+
type: fingerprint.source.type,
|
|
72
|
+
bucketKey: fingerprint.source.bucketKey,
|
|
73
|
+
isDebugFingerprint: fingerprint.source.isDebugFingerprint,
|
|
74
|
+
}
|
|
75
|
+
: undefined,
|
|
76
|
+
},
|
|
77
|
+
];
|
|
78
|
+
})),
|
|
60
79
|
};
|
|
61
80
|
updatesRepublished = await PublishMutation_1.PublishMutation.publishUpdateGroupAsync(graphqlClient, [
|
|
62
81
|
{
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function mapMapAsync<K, V, M>(map: ReadonlyMap<K, V>, mapper: (value: V, key: K) => Promise<M>): Promise<Map<K, M>>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
async function mapMapAsync(map, mapper) {
|
|
4
|
+
const resultingMap = new Map();
|
|
5
|
+
await Promise.all(Array.from(map.keys()).map(async (k) => {
|
|
6
|
+
const initialValue = map.get(k);
|
|
7
|
+
const result = await mapper(initialValue, k);
|
|
8
|
+
resultingMap.set(k, result);
|
|
9
|
+
}));
|
|
10
|
+
return resultingMap;
|
|
11
|
+
}
|
|
12
|
+
exports.default = mapMapAsync;
|
|
@@ -1,12 +1,30 @@
|
|
|
1
1
|
import { Env, Workflow } from '@expo/eas-build-job';
|
|
2
|
-
export
|
|
2
|
+
export type FingerprintOptions = {
|
|
3
3
|
workflow: Workflow;
|
|
4
|
-
|
|
4
|
+
platforms: string[];
|
|
5
5
|
debug?: boolean;
|
|
6
6
|
env: Env | undefined;
|
|
7
7
|
cwd?: string;
|
|
8
|
-
}
|
|
8
|
+
};
|
|
9
|
+
export declare function createFingerprintAsync(projectDir: string, options: FingerprintOptions): Promise<{
|
|
9
10
|
hash: string;
|
|
10
11
|
sources: object[];
|
|
11
12
|
isDebugSource: boolean;
|
|
12
13
|
} | null>;
|
|
14
|
+
/**
|
|
15
|
+
* Computes project fingerprints based on provided options and returns a map of fingerprint data keyed by a string.
|
|
16
|
+
*
|
|
17
|
+
* @param projectDir - The root directory of the project.
|
|
18
|
+
* @param fingerprintOptionsByKey - A map where each key is associated with options for generating the fingerprint.
|
|
19
|
+
* - **Key**: A unique identifier (`string`) for the fingerprint options.
|
|
20
|
+
* - **Value**: An object containing options for generating a fingerprint.
|
|
21
|
+
*
|
|
22
|
+
* @returns A promise that resolves to a map where each key corresponds to the input keys, and each value is an object containing fingerprint data.
|
|
23
|
+
*
|
|
24
|
+
* @throws Will throw an error if fingerprint computation fails.
|
|
25
|
+
*/
|
|
26
|
+
export declare function createFingerprintsByKeyAsync(projectDir: string, fingerprintOptionsByKey: Map<string, FingerprintOptions>): Promise<Map<string, {
|
|
27
|
+
hash: string;
|
|
28
|
+
sources: object[];
|
|
29
|
+
isDebugSource: boolean;
|
|
30
|
+
}>>;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createFingerprintAsync = void 0;
|
|
3
|
+
exports.createFingerprintsByKeyAsync = exports.createFingerprintAsync = void 0;
|
|
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"));
|
|
7
8
|
const log_1 = tslib_1.__importDefault(require("../log"));
|
|
8
9
|
const ora_1 = require("../ora");
|
|
9
10
|
async function createFingerprintAsync(projectDir, options) {
|
|
@@ -22,18 +23,7 @@ async function createFingerprintAsync(projectDir, options) {
|
|
|
22
23
|
}, 5000);
|
|
23
24
|
const spinner = (0, ora_1.ora)(`Computing project fingerprint`).start();
|
|
24
25
|
try {
|
|
25
|
-
const
|
|
26
|
-
const fingerprintOptions = {};
|
|
27
|
-
if (options.platform) {
|
|
28
|
-
fingerprintOptions.platforms = [options.platform];
|
|
29
|
-
}
|
|
30
|
-
if (options.workflow === eas_build_job_1.Workflow.MANAGED) {
|
|
31
|
-
fingerprintOptions.ignorePaths = ['android/**/*', 'ios/**/*'];
|
|
32
|
-
}
|
|
33
|
-
if (options.debug) {
|
|
34
|
-
fingerprintOptions.debug = true;
|
|
35
|
-
}
|
|
36
|
-
const fingerprint = await Fingerprint.createFingerprintAsync(projectDir, fingerprintOptions);
|
|
26
|
+
const fingerprint = await createFingerprintWithoutLoggingAsync(projectDir, fingerprintPath, options);
|
|
37
27
|
spinner.succeed(`Computed project fingerprint`);
|
|
38
28
|
return fingerprint;
|
|
39
29
|
}
|
|
@@ -49,3 +39,62 @@ async function createFingerprintAsync(projectDir, options) {
|
|
|
49
39
|
}
|
|
50
40
|
}
|
|
51
41
|
exports.createFingerprintAsync = createFingerprintAsync;
|
|
42
|
+
async function createFingerprintWithoutLoggingAsync(projectDir, fingerprintPath, options) {
|
|
43
|
+
const Fingerprint = require(fingerprintPath);
|
|
44
|
+
const fingerprintOptions = {};
|
|
45
|
+
if (options.platforms) {
|
|
46
|
+
fingerprintOptions.platforms = [...options.platforms];
|
|
47
|
+
}
|
|
48
|
+
if (options.workflow === eas_build_job_1.Workflow.MANAGED) {
|
|
49
|
+
fingerprintOptions.ignorePaths = ['android/**/*', 'ios/**/*'];
|
|
50
|
+
}
|
|
51
|
+
if (options.debug) {
|
|
52
|
+
fingerprintOptions.debug = true;
|
|
53
|
+
}
|
|
54
|
+
// eslint-disable-next-line @typescript-eslint/return-await
|
|
55
|
+
return await Fingerprint.createFingerprintAsync(projectDir, fingerprintOptions);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Computes project fingerprints based on provided options and returns a map of fingerprint data keyed by a string.
|
|
59
|
+
*
|
|
60
|
+
* @param projectDir - The root directory of the project.
|
|
61
|
+
* @param fingerprintOptionsByKey - A map where each key is associated with options for generating the fingerprint.
|
|
62
|
+
* - **Key**: A unique identifier (`string`) for the fingerprint options.
|
|
63
|
+
* - **Value**: An object containing options for generating a fingerprint.
|
|
64
|
+
*
|
|
65
|
+
* @returns A promise that resolves to a map where each key corresponds to the input keys, and each value is an object containing fingerprint data.
|
|
66
|
+
*
|
|
67
|
+
* @throws Will throw an error if fingerprint computation fails.
|
|
68
|
+
*/
|
|
69
|
+
async function createFingerprintsByKeyAsync(projectDir, fingerprintOptionsByKey) {
|
|
70
|
+
// @expo/fingerprint is exported in the expo package for SDK 52+
|
|
71
|
+
const fingerprintPath = (0, resolve_from_1.silent)(projectDir, 'expo/fingerprint');
|
|
72
|
+
if (!fingerprintPath) {
|
|
73
|
+
return new Map();
|
|
74
|
+
}
|
|
75
|
+
if (process.env.EAS_SKIP_AUTO_FINGERPRINT) {
|
|
76
|
+
log_1.default.log('Skipping project fingerprints');
|
|
77
|
+
return new Map();
|
|
78
|
+
}
|
|
79
|
+
const timeoutId = setTimeout(() => {
|
|
80
|
+
log_1.default.log('⌛️ Computing the project fingerprints is taking longer than expected...');
|
|
81
|
+
log_1.default.log('⏩ To skip this step, set the environment variable: EAS_SKIP_AUTO_FINGERPRINT=1');
|
|
82
|
+
}, 5000);
|
|
83
|
+
const spinner = (0, ora_1.ora)(`Computing project fingerprints`).start();
|
|
84
|
+
try {
|
|
85
|
+
const fingerprintsByKey = await (0, mapMapAsync_1.default)(fingerprintOptionsByKey, async (options) => await createFingerprintWithoutLoggingAsync(projectDir, fingerprintPath, options));
|
|
86
|
+
spinner.succeed(`Computed project fingerprints`);
|
|
87
|
+
return fingerprintsByKey;
|
|
88
|
+
}
|
|
89
|
+
catch (e) {
|
|
90
|
+
spinner.fail(`Failed to compute project fingerprints`);
|
|
91
|
+
log_1.default.log('⏩ To skip this step, set the environment variable: EAS_SKIP_AUTO_FINGERPRINT=1');
|
|
92
|
+
throw e;
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
// Clear the timeout if the operation finishes before the time limit
|
|
96
|
+
clearTimeout(timeoutId);
|
|
97
|
+
spinner.stop();
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
exports.createFingerprintsByKeyAsync = createFingerprintsByKeyAsync;
|
package/build/utils/prompts.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { EnvironmentSecretType, EnvironmentVariableEnvironment, EnvironmentVariableVisibility } from '../graphql/generated';
|
|
2
2
|
export declare function promptVariableTypeAsync(nonInteractive: boolean, initialType?: EnvironmentSecretType): Promise<EnvironmentSecretType>;
|
|
3
|
-
export declare function parseVisibility(stringVisibility: 'plaintext' | 'sensitive' | '
|
|
3
|
+
export declare function parseVisibility(stringVisibility: 'plaintext' | 'sensitive' | 'secret'): EnvironmentVariableVisibility;
|
|
4
4
|
export declare function promptVariableVisibilityAsync(nonInteractive: boolean, selectedVisibility?: EnvironmentVariableVisibility | null): Promise<EnvironmentVariableVisibility>;
|
|
5
5
|
type EnvironmentPromptArgs = {
|
|
6
6
|
nonInteractive: boolean;
|
package/build/utils/prompts.js
CHANGED
|
@@ -30,7 +30,7 @@ function parseVisibility(stringVisibility) {
|
|
|
30
30
|
return generated_1.EnvironmentVariableVisibility.Public;
|
|
31
31
|
case 'sensitive':
|
|
32
32
|
return generated_1.EnvironmentVariableVisibility.Sensitive;
|
|
33
|
-
case '
|
|
33
|
+
case 'secret':
|
|
34
34
|
return generated_1.EnvironmentVariableVisibility.Secret;
|
|
35
35
|
default:
|
|
36
36
|
throw new Error(`Invalid visibility: ${stringVisibility}`);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { CombinedError } from '@urql/core';
|
|
2
|
+
export declare namespace WorkflowFile {
|
|
3
|
+
function readWorkflowFileContentsAsync({ projectDir, filePath, }: {
|
|
4
|
+
projectDir: string;
|
|
5
|
+
filePath: string;
|
|
6
|
+
}): Promise<{
|
|
7
|
+
yamlConfig: string;
|
|
8
|
+
filePath: string;
|
|
9
|
+
}>;
|
|
10
|
+
function maybePrintWorkflowFileValidationErrors({ error, accountName, projectName, }: {
|
|
11
|
+
error: CombinedError;
|
|
12
|
+
accountName: string;
|
|
13
|
+
projectName: string;
|
|
14
|
+
}): void;
|
|
15
|
+
function validateYamlExtension(fileName: string): void;
|
|
16
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WorkflowFile = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const fs_1 = tslib_1.__importDefault(require("fs"));
|
|
6
|
+
const path_1 = tslib_1.__importDefault(require("path"));
|
|
7
|
+
const url_1 = require("../build/utils/url");
|
|
8
|
+
const WorkflowRevisionMutation_1 = require("../graphql/mutations/WorkflowRevisionMutation");
|
|
9
|
+
const log_1 = tslib_1.__importStar(require("../log"));
|
|
10
|
+
var WorkflowFile;
|
|
11
|
+
(function (WorkflowFile) {
|
|
12
|
+
async function readWorkflowFileContentsAsync({ projectDir, filePath, }) {
|
|
13
|
+
const [yamlFromEasWorkflowsFile, yamlFromFile] = await Promise.allSettled([
|
|
14
|
+
fs_1.default.promises.readFile(path_1.default.join(projectDir, '.eas', 'workflows', filePath), 'utf8'),
|
|
15
|
+
fs_1.default.promises.readFile(path_1.default.join(process.cwd(), filePath), 'utf8'),
|
|
16
|
+
]);
|
|
17
|
+
// We prioritize .eas/workflows/${file} over ${file}, because
|
|
18
|
+
// in the worst case we'll try to read .eas/workflows/.eas/workflows/test.yml,
|
|
19
|
+
// which is likely not to exist.
|
|
20
|
+
if (yamlFromEasWorkflowsFile.status === 'fulfilled') {
|
|
21
|
+
return {
|
|
22
|
+
yamlConfig: yamlFromEasWorkflowsFile.value,
|
|
23
|
+
filePath: path_1.default.join(projectDir, '.eas', 'workflows', filePath),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
else if (yamlFromFile.status === 'fulfilled') {
|
|
27
|
+
return {
|
|
28
|
+
yamlConfig: yamlFromFile.value,
|
|
29
|
+
filePath: path_1.default.join(process.cwd(), filePath),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
throw yamlFromFile.reason;
|
|
33
|
+
}
|
|
34
|
+
WorkflowFile.readWorkflowFileContentsAsync = readWorkflowFileContentsAsync;
|
|
35
|
+
function maybePrintWorkflowFileValidationErrors({ error, accountName, projectName, }) {
|
|
36
|
+
const validationErrors = error.graphQLErrors.flatMap(e => {
|
|
37
|
+
return WorkflowRevisionMutation_1.WorkflowRevisionMutation.ValidationErrorExtensionZ.safeParse(e.extensions).data ?? [];
|
|
38
|
+
});
|
|
39
|
+
if (validationErrors.length > 0) {
|
|
40
|
+
log_1.default.error('Workflow file is invalid. Issues:');
|
|
41
|
+
for (const validationError of validationErrors) {
|
|
42
|
+
for (const formError of validationError.metadata.formErrors) {
|
|
43
|
+
log_1.default.error(`- ${formError}`);
|
|
44
|
+
}
|
|
45
|
+
for (const [field, fieldErrors] of Object.entries(validationError.metadata.fieldErrors)) {
|
|
46
|
+
log_1.default.error(`- ${field}: ${fieldErrors.join(', ')}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const githubNotFoundError = error.graphQLErrors.find(e => e.extensions.errorCode === 'GITHUB_NOT_FOUND_ERROR');
|
|
51
|
+
if (githubNotFoundError) {
|
|
52
|
+
log_1.default.error(`GitHub repository not found. It is currently required to run workflows.`);
|
|
53
|
+
log_1.default.error(`Please check that the repository exists and that you have access to it. ${(0, log_1.link)((0, url_1.getProjectGitHubSettingsUrl)(accountName, projectName))}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
WorkflowFile.maybePrintWorkflowFileValidationErrors = maybePrintWorkflowFileValidationErrors;
|
|
57
|
+
function validateYamlExtension(fileName) {
|
|
58
|
+
const fileExtension = path_1.default.extname(fileName).toLowerCase();
|
|
59
|
+
if (fileExtension !== '.yml' && fileExtension !== '.yaml') {
|
|
60
|
+
throw new Error('File must have a .yml or .yaml extension');
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
WorkflowFile.validateYamlExtension = validateYamlExtension;
|
|
64
|
+
})(WorkflowFile || (exports.WorkflowFile = WorkflowFile = {}));
|