eas-cli 14.4.1 → 14.6.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 +147 -91
- package/build/build/android/graphql.js +2 -0
- package/build/build/android/prepareJob.js +1 -0
- package/build/build/android/version.d.ts +1 -0
- package/build/build/android/version.js +5 -1
- package/build/build/build.js +4 -3
- package/build/build/configure.d.ts +11 -0
- package/build/build/configure.js +46 -1
- package/build/build/evaluateConfigWithEnvVarsAsync.js +2 -4
- package/build/build/ios/build.js +2 -0
- package/build/build/ios/graphql.js +2 -0
- package/build/build/ios/prepareJob.js +1 -0
- package/build/build/ios/version.js +4 -1
- package/build/build/local.js +1 -1
- package/build/build/metadata.js +0 -1
- package/build/build/runBuildAndSubmit.d.ts +12 -1
- package/build/build/runBuildAndSubmit.js +16 -13
- package/build/build/utils/environment.d.ts +4 -0
- package/build/build/utils/environment.js +20 -0
- package/build/commands/build/dev.d.ts +23 -0
- package/build/commands/build/dev.js +225 -0
- package/build/commands/build/index.js +9 -1
- package/build/commands/build/inspect.js +26 -18
- package/build/commands/build/internal.js +22 -14
- package/build/commands/build/list.d.ts +1 -0
- package/build/commands/build/list.js +4 -0
- package/build/commands/{worker → deploy}/alias.js +4 -4
- package/build/commands/{worker/deploy.js → deploy/index.js} +5 -5
- package/build/commands/fingerprint/compare.d.ts +14 -1
- package/build/commands/fingerprint/compare.js +192 -53
- package/build/commands/project/onboarding.js +23 -14
- package/build/commands/update/index.js +3 -6
- package/build/commands/update/roll-back-to-embedded.js +2 -2
- package/build/credentials/ios/appstore/ensureAppExists.d.ts +22 -1
- package/build/credentials/ios/appstore/ensureAppExists.js +73 -2
- package/build/credentials/ios/appstore/ensureTestFlightGroup.d.ts +7 -0
- package/build/credentials/ios/appstore/ensureTestFlightGroup.js +158 -0
- package/build/credentials/ios/appstore/provisioningProfile.js +1 -0
- package/build/credentials/ios/appstore/resolveCredentials.js +6 -1
- package/build/graphql/generated.d.ts +313 -3
- package/build/graphql/generated.js +11 -2
- package/build/graphql/queries/FingerprintQuery.d.ts +16 -0
- package/build/graphql/queries/FingerprintQuery.js +61 -0
- package/build/graphql/types/Fingerprint.js +18 -0
- package/build/project/ios/exemptEncryption.d.ts +7 -0
- package/build/project/ios/exemptEncryption.js +80 -0
- package/build/project/publish.d.ts +4 -4
- package/build/project/publish.js +9 -8
- package/build/project/resolveRuntimeVersionAsync.d.ts +4 -4
- package/build/project/resolveRuntimeVersionAsync.js +4 -4
- package/build/submit/ios/AppProduce.js +12 -23
- package/build/utils/fingerprintCli.d.ts +2 -1
- package/build/utils/fingerprintCli.js +11 -3
- package/build/worker/upload.js +19 -3
- package/oclif.manifest.json +217 -155
- package/package.json +6 -6
- /package/build/commands/{worker → deploy}/alias.d.ts +0 -0
- /package/build/commands/{worker/deploy.d.ts → deploy/index.d.ts} +0 -0
|
@@ -8,5 +8,23 @@ exports.FingerprintFragmentNode = (0, graphql_tag_1.default) `
|
|
|
8
8
|
id
|
|
9
9
|
hash
|
|
10
10
|
debugInfoUrl
|
|
11
|
+
builds(first: 1) {
|
|
12
|
+
edges {
|
|
13
|
+
node {
|
|
14
|
+
id
|
|
15
|
+
... on Build {
|
|
16
|
+
platform
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
updates(first: 1) {
|
|
22
|
+
edges {
|
|
23
|
+
node {
|
|
24
|
+
id
|
|
25
|
+
platform
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
11
29
|
}
|
|
12
30
|
`;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ExpoConfig } from '@expo/config';
|
|
2
|
+
/** Non-exempt encryption must be set on every build in App Store Connect, we move it to before the build process to attempt only setting it once for the entire life-cycle of the project. */
|
|
3
|
+
export declare function ensureNonExemptEncryptionIsDefinedForManagedProjectAsync({ projectDir, exp, nonInteractive, }: {
|
|
4
|
+
projectDir: string;
|
|
5
|
+
exp: ExpoConfig;
|
|
6
|
+
nonInteractive: boolean;
|
|
7
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ensureNonExemptEncryptionIsDefinedForManagedProjectAsync = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const config_1 = require("@expo/config");
|
|
6
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
7
|
+
const log_1 = tslib_1.__importStar(require("../../log"));
|
|
8
|
+
const prompts_1 = require("../../prompts");
|
|
9
|
+
/** Non-exempt encryption must be set on every build in App Store Connect, we move it to before the build process to attempt only setting it once for the entire life-cycle of the project. */
|
|
10
|
+
async function ensureNonExemptEncryptionIsDefinedForManagedProjectAsync({ projectDir, exp, nonInteractive, }) {
|
|
11
|
+
// TODO: We could add bare workflow support in the future.
|
|
12
|
+
// TODO: We could add wizard support for non-exempt encryption in the future.
|
|
13
|
+
if (exp.ios?.infoPlist?.ITSAppUsesNonExemptEncryption == null) {
|
|
14
|
+
await configureNonExemptEncryptionAsync({
|
|
15
|
+
projectDir,
|
|
16
|
+
exp,
|
|
17
|
+
nonInteractive,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
log_1.default.debug(`ITSAppUsesNonExemptEncryption is defined in the app config.`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.ensureNonExemptEncryptionIsDefinedForManagedProjectAsync = ensureNonExemptEncryptionIsDefinedForManagedProjectAsync;
|
|
25
|
+
async function configureNonExemptEncryptionAsync({ projectDir, exp, nonInteractive, }) {
|
|
26
|
+
const description = (0, config_1.getProjectConfigDescription)(projectDir);
|
|
27
|
+
if (nonInteractive) {
|
|
28
|
+
log_1.default.warn((0, chalk_1.default) `${description} is missing {bold ios.infoPlist.ITSAppUsesNonExemptEncryption} boolean. Manual configuration is required in App Store Connect before the app can be tested.`);
|
|
29
|
+
}
|
|
30
|
+
let onlyExemptEncryption = await (0, prompts_1.confirmAsync)({
|
|
31
|
+
message: `iOS app only uses standard/exempt encryption? ${chalk_1.default.dim((0, log_1.learnMore)('https://developer.apple.com/documentation/Security/complying-with-encryption-export-regulations'))}`,
|
|
32
|
+
initial: true,
|
|
33
|
+
});
|
|
34
|
+
if (!onlyExemptEncryption) {
|
|
35
|
+
const confirm = await (0, prompts_1.confirmAsync)({
|
|
36
|
+
message: `Are you sure your app uses non-exempt encryption? Selecting 'Yes' will require annual self-classification reports for the US government.`,
|
|
37
|
+
initial: true,
|
|
38
|
+
});
|
|
39
|
+
if (!confirm) {
|
|
40
|
+
log_1.default.warn((0, chalk_1.default) `Set {bold ios.infoPlist.ITSAppUsesNonExemptEncryption} in ${description} to release Apple builds faster.`);
|
|
41
|
+
onlyExemptEncryption = true;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const ITSAppUsesNonExemptEncryption = !onlyExemptEncryption;
|
|
45
|
+
// Only set this value if the answer is no, this enables developers to see the more in-depth prompt in App Store Connect. They can set the value manually in the app.json to avoid the EAS prompt in subsequent builds.
|
|
46
|
+
if (ITSAppUsesNonExemptEncryption) {
|
|
47
|
+
log_1.default.warn(`You'll need to manually configure the encryption status in App Store Connect before your build can be tested.`);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
// NOTE: Is is it possible to assert that the config needs to be modifiable before building the app?
|
|
51
|
+
const modification = await (0, config_1.modifyConfigAsync)(projectDir, {
|
|
52
|
+
ios: {
|
|
53
|
+
...(exp.ios ?? {}),
|
|
54
|
+
infoPlist: {
|
|
55
|
+
...(exp.ios?.infoPlist ?? {}),
|
|
56
|
+
ITSAppUsesNonExemptEncryption,
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
}, {
|
|
60
|
+
skipSDKVersionRequirement: true,
|
|
61
|
+
});
|
|
62
|
+
if (modification.type !== 'success') {
|
|
63
|
+
log_1.default.log();
|
|
64
|
+
if (modification.type === 'warn') {
|
|
65
|
+
// The project is using a dynamic config, give the user a helpful log and bail out.
|
|
66
|
+
log_1.default.log(chalk_1.default.yellow(modification.message));
|
|
67
|
+
}
|
|
68
|
+
const edits = {
|
|
69
|
+
ios: {
|
|
70
|
+
infoPlist: {
|
|
71
|
+
ITSAppUsesNonExemptEncryption,
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
log_1.default.log(chalk_1.default.cyan(`Add the following to ${description}:`));
|
|
76
|
+
log_1.default.log();
|
|
77
|
+
log_1.default.log(JSON.stringify(edits, null, 2));
|
|
78
|
+
log_1.default.log();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -145,11 +145,11 @@ export declare function getUpdateMessageForCommandAsync(vcsClient: Client, { upd
|
|
|
145
145
|
export declare const defaultPublishPlatforms: UpdatePublishPlatform[];
|
|
146
146
|
export type RuntimeVersionInfo = {
|
|
147
147
|
runtimeVersion: string;
|
|
148
|
-
|
|
148
|
+
expoUpdatesRuntimeFingerprint: {
|
|
149
149
|
fingerprintSources: object[];
|
|
150
150
|
isDebugFingerprintSource: boolean;
|
|
151
151
|
} | null;
|
|
152
|
-
|
|
152
|
+
expoUpdatesRuntimeFingerprintHash: string | null;
|
|
153
153
|
};
|
|
154
154
|
type FingerprintInfoGroup = {
|
|
155
155
|
[key in UpdatePublishPlatform]?: FingerprintInfo;
|
|
@@ -179,13 +179,13 @@ export declare function maybeCalculateFingerprintForRuntimeVersionInfoObjectsWit
|
|
|
179
179
|
graphqlClient: ExpoGraphqlClient;
|
|
180
180
|
runtimeToPlatformsAndFingerprintInfoAndFingerprintSourceMapping: (RuntimeVersionInfo & {
|
|
181
181
|
platforms: UpdatePublishPlatform[];
|
|
182
|
-
|
|
182
|
+
expoUpdatesRuntimeFingerprintSource: FingerprintSource | null;
|
|
183
183
|
})[];
|
|
184
184
|
workflowsByPlatform: Record<Platform, Workflow>;
|
|
185
185
|
env: Env | undefined;
|
|
186
186
|
}): Promise<(RuntimeVersionInfo & {
|
|
187
187
|
platforms: UpdatePublishPlatform[];
|
|
188
|
-
|
|
188
|
+
expoUpdatesRuntimeFingerprintSource: FingerprintSource | null;
|
|
189
189
|
fingerprintInfoGroup: FingerprintInfoGroup;
|
|
190
190
|
})[]>;
|
|
191
191
|
export declare const platformDisplayNames: Record<UpdatePublishPlatform, string>;
|
package/build/project/publish.js
CHANGED
|
@@ -520,8 +520,8 @@ async function getRuntimeVersionInfoForPlatformAsync({ exp, platform, workflow,
|
|
|
520
520
|
}
|
|
521
521
|
return {
|
|
522
522
|
runtimeVersion: resolvedRuntimeVersion,
|
|
523
|
-
|
|
524
|
-
|
|
523
|
+
expoUpdatesRuntimeFingerprint: null,
|
|
524
|
+
expoUpdatesRuntimeFingerprintHash: null,
|
|
525
525
|
};
|
|
526
526
|
}
|
|
527
527
|
function getRuntimeToPlatformsAndFingerprintInfoMappingFromRuntimeVersionInfoObjects(runtimeVersionInfoObjects) {
|
|
@@ -530,14 +530,14 @@ function getRuntimeToPlatformsAndFingerprintInfoMappingFromRuntimeVersionInfoObj
|
|
|
530
530
|
return {
|
|
531
531
|
runtimeVersion,
|
|
532
532
|
platforms: runtimeVersionInfoObjects.map(runtimeVersionInfoObject => runtimeVersionInfoObject.platform),
|
|
533
|
-
|
|
534
|
-
|
|
533
|
+
expoUpdatesRuntimeFingerprint: runtimeVersionInfoObjects.map(runtimeVersionInfoObject => runtimeVersionInfoObject.runtimeVersionInfo.expoUpdatesRuntimeFingerprint)[0] ?? null,
|
|
534
|
+
expoUpdatesRuntimeFingerprintHash: runtimeVersionInfoObjects.map(runtimeVersionInfoObject => runtimeVersionInfoObject.runtimeVersionInfo.expoUpdatesRuntimeFingerprintHash)[0] ?? null,
|
|
535
535
|
};
|
|
536
536
|
});
|
|
537
537
|
}
|
|
538
538
|
exports.getRuntimeToPlatformsAndFingerprintInfoMappingFromRuntimeVersionInfoObjects = getRuntimeToPlatformsAndFingerprintInfoMappingFromRuntimeVersionInfoObjects;
|
|
539
539
|
async function maybeCalculateFingerprintForRuntimeVersionInfoObjectsWithoutExpoUpdatesAsync({ projectDir, graphqlClient, runtimeToPlatformsAndFingerprintInfoAndFingerprintSourceMapping, workflowsByPlatform, env, }) {
|
|
540
|
-
const runtimesToComputeFingerprintsFor = runtimeToPlatformsAndFingerprintInfoAndFingerprintSourceMapping.filter(infoGroup => !infoGroup.
|
|
540
|
+
const runtimesToComputeFingerprintsFor = runtimeToPlatformsAndFingerprintInfoAndFingerprintSourceMapping.filter(infoGroup => !infoGroup.expoUpdatesRuntimeFingerprintHash);
|
|
541
541
|
const fingerprintOptionsByRuntimeAndPlatform = new Map();
|
|
542
542
|
for (const infoGroup of runtimesToComputeFingerprintsFor) {
|
|
543
543
|
for (const platform of infoGroup.platforms) {
|
|
@@ -584,15 +584,16 @@ async function maybeCalculateFingerprintForRuntimeVersionInfoObjectsWithoutExpoU
|
|
|
584
584
|
});
|
|
585
585
|
// These are runtimes whose fingerprint has already been computed and uploaded with EAS Update fingerprint runtime policy
|
|
586
586
|
const runtimesWithPreviouslyComputedFingerprints = runtimeToPlatformsAndFingerprintInfoAndFingerprintSourceMapping
|
|
587
|
-
.filter((infoGroup) => !!infoGroup.
|
|
587
|
+
.filter((infoGroup) => !!infoGroup.expoUpdatesRuntimeFingerprintHash &&
|
|
588
|
+
!!infoGroup.expoUpdatesRuntimeFingerprintSource)
|
|
588
589
|
.map(infoGroup => {
|
|
589
590
|
const platform = infoGroup.platforms[0];
|
|
590
591
|
return {
|
|
591
592
|
...infoGroup,
|
|
592
593
|
fingerprintInfoGroup: {
|
|
593
594
|
[platform]: {
|
|
594
|
-
fingerprintHash: infoGroup.
|
|
595
|
-
fingerprintSource: infoGroup.
|
|
595
|
+
fingerprintHash: infoGroup.expoUpdatesRuntimeFingerprintHash,
|
|
596
|
+
fingerprintSource: infoGroup.expoUpdatesRuntimeFingerprintSource,
|
|
596
597
|
},
|
|
597
598
|
},
|
|
598
599
|
};
|
|
@@ -8,11 +8,11 @@ export declare function resolveRuntimeVersionUsingCLIAsync({ platform, workflow,
|
|
|
8
8
|
cwd?: string;
|
|
9
9
|
}): Promise<{
|
|
10
10
|
runtimeVersion: string | null;
|
|
11
|
-
|
|
11
|
+
expoUpdatesRuntimeFingerprint: {
|
|
12
12
|
fingerprintSources: object[];
|
|
13
13
|
isDebugFingerprintSource: boolean;
|
|
14
14
|
} | null;
|
|
15
|
-
|
|
15
|
+
expoUpdatesRuntimeFingerprintHash: string | null;
|
|
16
16
|
}>;
|
|
17
17
|
export declare function resolveRuntimeVersionAsync({ exp, platform, workflow, projectDir, env, cwd, }: {
|
|
18
18
|
exp: ExpoConfig;
|
|
@@ -23,9 +23,9 @@ export declare function resolveRuntimeVersionAsync({ exp, platform, workflow, pr
|
|
|
23
23
|
cwd?: string;
|
|
24
24
|
}): Promise<{
|
|
25
25
|
runtimeVersion: string | null;
|
|
26
|
-
|
|
26
|
+
expoUpdatesRuntimeFingerprint: {
|
|
27
27
|
fingerprintSources: object[];
|
|
28
28
|
isDebugFingerprintSource: boolean;
|
|
29
29
|
} | null;
|
|
30
|
-
|
|
30
|
+
expoUpdatesRuntimeFingerprintHash: string | null;
|
|
31
31
|
} | null>;
|
|
@@ -16,13 +16,13 @@ async function resolveRuntimeVersionUsingCLIAsync({ platform, workflow, projectD
|
|
|
16
16
|
log_1.default.debug(resolvedRuntimeVersionJSONResult);
|
|
17
17
|
return {
|
|
18
18
|
runtimeVersion: runtimeVersionResult.runtimeVersion ?? null,
|
|
19
|
-
|
|
19
|
+
expoUpdatesRuntimeFingerprint: runtimeVersionResult.fingerprintSources
|
|
20
20
|
? {
|
|
21
21
|
fingerprintSources: runtimeVersionResult.fingerprintSources,
|
|
22
22
|
isDebugFingerprintSource: useDebugFingerprintSource,
|
|
23
23
|
}
|
|
24
24
|
: null,
|
|
25
|
-
|
|
25
|
+
expoUpdatesRuntimeFingerprintHash: runtimeVersionResult.fingerprintSources
|
|
26
26
|
? runtimeVersionResult.runtimeVersion
|
|
27
27
|
: null,
|
|
28
28
|
};
|
|
@@ -34,8 +34,8 @@ async function resolveRuntimeVersionAsync({ exp, platform, workflow, projectDir,
|
|
|
34
34
|
// than the versioned @expo/config-plugins dependency in the project)
|
|
35
35
|
return {
|
|
36
36
|
runtimeVersion: await config_plugins_1.Updates.getRuntimeVersionNullableAsync(projectDir, exp, platform),
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
expoUpdatesRuntimeFingerprint: null,
|
|
38
|
+
expoUpdatesRuntimeFingerprintHash: null,
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
41
|
try {
|
|
@@ -3,10 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ensureAppStoreConnectAppExistsAsync = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const apple_utils_1 = require("@expo/apple-utils");
|
|
6
|
-
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
7
6
|
const language_1 = require("./utils/language");
|
|
8
7
|
const authenticate_1 = require("../../credentials/ios/appstore/authenticate");
|
|
9
8
|
const ensureAppExists_1 = require("../../credentials/ios/appstore/ensureAppExists");
|
|
9
|
+
const ensureTestFlightGroup_1 = require("../../credentials/ios/appstore/ensureTestFlightGroup");
|
|
10
10
|
const log_1 = tslib_1.__importDefault(require("../../log"));
|
|
11
11
|
const bundleIdentifier_1 = require("../../project/ios/bundleIdentifier");
|
|
12
12
|
const prompts_1 = require("../../prompts");
|
|
@@ -48,31 +48,20 @@ async function createAppStoreConnectAppAsync(ctx, options) {
|
|
|
48
48
|
else {
|
|
49
49
|
log_1.default.warn(`Provisioning is not available for Apple User: ${userAuthCtx.appleId}, skipping bundle identifier check.`);
|
|
50
50
|
}
|
|
51
|
-
|
|
51
|
+
const app = await (0, ensureAppExists_1.ensureAppExistsAsync)(userAuthCtx, {
|
|
52
|
+
name: appName,
|
|
53
|
+
language,
|
|
54
|
+
companyName,
|
|
55
|
+
bundleIdentifier: bundleId,
|
|
56
|
+
sku,
|
|
57
|
+
});
|
|
52
58
|
try {
|
|
53
|
-
|
|
54
|
-
name: appName,
|
|
55
|
-
language,
|
|
56
|
-
companyName,
|
|
57
|
-
bundleIdentifier: bundleId,
|
|
58
|
-
sku,
|
|
59
|
-
});
|
|
59
|
+
await (0, ensureTestFlightGroup_1.ensureTestFlightGroupExistsAsync)(app);
|
|
60
60
|
}
|
|
61
61
|
catch (error) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
// UnexpectedAppleResponse: An attribute value has invalid characters. - App Name contains certain Unicode symbols, emoticons, diacritics, special characters, or private use characters that are not permitted.
|
|
66
|
-
// Name is taken
|
|
67
|
-
error.message.match(/The App Name you entered is already being used/)
|
|
68
|
-
// UnexpectedAppleResponse: The provided entity includes an attribute with a value that has already been used on a different account. - The App Name you entered is already being used. If you have trademark rights to
|
|
69
|
-
// this name and would like it released for your use, submit a claim.
|
|
70
|
-
) {
|
|
71
|
-
log_1.default.addNewLineIfNone();
|
|
72
|
-
log_1.default.warn(`Change the name in your app config, or use a custom name with the ${chalk_1.default.bold('--app-name')} flag`);
|
|
73
|
-
log_1.default.newLine();
|
|
74
|
-
}
|
|
75
|
-
throw error;
|
|
62
|
+
// This process is not critical to the app submission so we shouldn't let it fail the entire process.
|
|
63
|
+
log_1.default.error('Failed to create an internal TestFlight group. This can be done manually in the App Store Connect website.');
|
|
64
|
+
log_1.default.error(error);
|
|
76
65
|
}
|
|
77
66
|
return {
|
|
78
67
|
ascAppIdentifier: app.id,
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { Env, Workflow } from '@expo/eas-build-job';
|
|
2
2
|
import { Fingerprint, FingerprintDiffItem } from './fingerprint';
|
|
3
3
|
export type FingerprintOptions = {
|
|
4
|
-
workflow
|
|
4
|
+
workflow?: Workflow;
|
|
5
5
|
platforms: string[];
|
|
6
6
|
debug?: boolean;
|
|
7
7
|
env: Env | undefined;
|
|
8
8
|
cwd?: string;
|
|
9
|
+
ignorePaths?: string[];
|
|
9
10
|
};
|
|
10
11
|
export declare function diffFingerprint(projectDir: string, fingerprint1: Fingerprint, fingerprint2: Fingerprint): FingerprintDiffItem[] | null;
|
|
11
12
|
export declare function createFingerprintAsync(projectDir: string, options: FingerprintOptions): Promise<(Fingerprint & {
|
|
@@ -52,12 +52,20 @@ exports.createFingerprintAsync = createFingerprintAsync;
|
|
|
52
52
|
async function createFingerprintWithoutLoggingAsync(projectDir, fingerprintPath, options) {
|
|
53
53
|
const Fingerprint = require(fingerprintPath);
|
|
54
54
|
const fingerprintOptions = {};
|
|
55
|
+
const ignorePaths = [];
|
|
56
|
+
if (options.workflow === eas_build_job_1.Workflow.MANAGED) {
|
|
57
|
+
ignorePaths.push('android/**/*');
|
|
58
|
+
ignorePaths.push('ios/**/*');
|
|
59
|
+
}
|
|
60
|
+
if (options.ignorePaths) {
|
|
61
|
+
ignorePaths.push(...options.ignorePaths);
|
|
62
|
+
}
|
|
63
|
+
if (ignorePaths.length > 0) {
|
|
64
|
+
fingerprintOptions.ignorePaths = ignorePaths;
|
|
65
|
+
}
|
|
55
66
|
if (options.platforms) {
|
|
56
67
|
fingerprintOptions.platforms = [...options.platforms];
|
|
57
68
|
}
|
|
58
|
-
if (options.workflow === eas_build_job_1.Workflow.MANAGED) {
|
|
59
|
-
fingerprintOptions.ignorePaths = ['android/**/*', 'ios/**/*'];
|
|
60
|
-
}
|
|
61
69
|
if (options.debug) {
|
|
62
70
|
fingerprintOptions.debug = true;
|
|
63
71
|
}
|
package/build/worker/upload.js
CHANGED
|
@@ -8,6 +8,7 @@ const mime_1 = tslib_1.__importDefault(require("mime"));
|
|
|
8
8
|
const minizlib_1 = require("minizlib");
|
|
9
9
|
const node_fetch_1 = tslib_1.__importStar(require("node-fetch"));
|
|
10
10
|
const node_fs_1 = tslib_1.__importStar(require("node:fs"));
|
|
11
|
+
const promises_1 = require("node:fs/promises");
|
|
11
12
|
const node_path_1 = tslib_1.__importDefault(require("node:path"));
|
|
12
13
|
const promise_retry_1 = tslib_1.__importDefault(require("promise-retry"));
|
|
13
14
|
const MAX_RETRIES = 4;
|
|
@@ -32,6 +33,21 @@ const isCompressible = (contentType, size) => {
|
|
|
32
33
|
return true;
|
|
33
34
|
}
|
|
34
35
|
};
|
|
36
|
+
const getContentTypeAsync = async (filePath) => {
|
|
37
|
+
let contentType = mime_1.default.getType(node_path_1.default.basename(filePath));
|
|
38
|
+
if (!contentType) {
|
|
39
|
+
const fileContent = await (0, promises_1.readFile)(filePath, 'utf-8');
|
|
40
|
+
try {
|
|
41
|
+
// check if file is valid JSON without an extension, e.g. for the apple app site association file
|
|
42
|
+
const parsedData = JSON.parse(fileContent);
|
|
43
|
+
if (parsedData) {
|
|
44
|
+
contentType = 'application/json';
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch { }
|
|
48
|
+
}
|
|
49
|
+
return contentType;
|
|
50
|
+
};
|
|
35
51
|
let sharedAgent;
|
|
36
52
|
const getAgent = () => {
|
|
37
53
|
if (sharedAgent) {
|
|
@@ -52,11 +68,11 @@ const getAgent = () => {
|
|
|
52
68
|
};
|
|
53
69
|
async function uploadAsync(params) {
|
|
54
70
|
const { filePath, signal, compress, method = 'POST', url, headers: headersInit, ...requestInit } = params;
|
|
55
|
-
const stat = await node_fs_1.default.promises.stat(
|
|
71
|
+
const stat = await node_fs_1.default.promises.stat(filePath);
|
|
56
72
|
if (stat.size > MAX_UPLOAD_SIZE) {
|
|
57
|
-
throw new Error(`Upload of "${
|
|
73
|
+
throw new Error(`Upload of "${filePath}" aborted: File size is greater than the upload limit (>500MB)`);
|
|
58
74
|
}
|
|
59
|
-
const contentType =
|
|
75
|
+
const contentType = await getContentTypeAsync(filePath);
|
|
60
76
|
return await (0, promise_retry_1.default)(async (retry) => {
|
|
61
77
|
const headers = new node_fetch_1.Headers(headersInit);
|
|
62
78
|
if (contentType) {
|