eas-cli 14.7.1 → 15.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 +88 -81
- package/build/commands/build/internal.js +7 -3
- package/build/commands/fingerprint/compare.d.ts +2 -8
- package/build/commands/fingerprint/compare.js +218 -66
- package/build/commands/project/onboarding.js +4 -1
- package/build/commands/submit/internal.js +7 -3
- package/build/graphql/generated.d.ts +74 -0
- package/build/graphql/queries/UpdateQuery.d.ts +2 -1
- package/build/graphql/queries/UpdateQuery.js +16 -0
- package/build/graphql/types/Update.js +1 -0
- package/build/vcs/clients/git.d.ts +6 -2
- package/build/vcs/clients/git.js +87 -27
- package/build/vcs/index.js +10 -10
- package/build/vcs/local.d.ts +1 -0
- package/build/vcs/local.js +3 -3
- package/oclif.manifest.json +17 -5
- package/package.json +3 -3
- package/build/vcs/clients/gitNoCommit.d.ts +0 -8
- package/build/vcs/clients/gitNoCommit.js +0 -42
|
@@ -7,8 +7,7 @@ const local_1 = require("../../build/local");
|
|
|
7
7
|
const runBuildAndSubmit_1 = require("../../build/runBuildAndSubmit");
|
|
8
8
|
const EasCommand_1 = tslib_1.__importDefault(require("../../commandUtils/EasCommand"));
|
|
9
9
|
const json_1 = require("../../utils/json");
|
|
10
|
-
const
|
|
11
|
-
const noVcs_1 = tslib_1.__importDefault(require("../../vcs/clients/noVcs"));
|
|
10
|
+
const git_1 = tslib_1.__importDefault(require("../../vcs/clients/git"));
|
|
12
11
|
/**
|
|
13
12
|
* This command will be run on the EAS Build workers, when building
|
|
14
13
|
* directly from git. This command resolves credentials and other
|
|
@@ -52,9 +51,14 @@ class BuildInternal extends EasCommand_1.default {
|
|
|
52
51
|
(0, json_1.enableJsonOutput)();
|
|
53
52
|
const { loggedIn: { actor, graphqlClient }, getDynamicPrivateProjectConfigAsync, projectDir, analytics, vcsClient, } = await this.getContextAsync(BuildInternal, {
|
|
54
53
|
nonInteractive: true,
|
|
55
|
-
vcsClientOverride: process.env.EAS_NO_VCS ? new noVcs_1.default() : new gitNoCommit_1.default(),
|
|
56
54
|
withServerSideEnvironment: null,
|
|
57
55
|
});
|
|
56
|
+
if (vcsClient instanceof git_1.default) {
|
|
57
|
+
// `build:internal` is run on EAS workers and the repo may have been changed
|
|
58
|
+
// by pre-install hooks or other scripts. We don't want to require committing changes
|
|
59
|
+
// to continue the build.
|
|
60
|
+
vcsClient.requireCommit = false;
|
|
61
|
+
}
|
|
58
62
|
await (0, _1.handleDeprecatedEasJsonAsync)(projectDir, flags.nonInteractive);
|
|
59
63
|
await (0, runBuildAndSubmit_1.runBuildAndSubmitAsync)({
|
|
60
64
|
graphqlClient,
|
|
@@ -2,13 +2,6 @@ import EasCommand from '../../commandUtils/EasCommand';
|
|
|
2
2
|
import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
|
|
3
3
|
import { BuildStatus } from '../../graphql/generated';
|
|
4
4
|
import { RequestedPlatform } from '../../platform';
|
|
5
|
-
export interface FingerprintCompareFlags {
|
|
6
|
-
buildId?: string;
|
|
7
|
-
hash1?: string;
|
|
8
|
-
hash2?: string;
|
|
9
|
-
nonInteractive: boolean;
|
|
10
|
-
json: boolean;
|
|
11
|
-
}
|
|
12
5
|
export default class FingerprintCompare extends EasCommand {
|
|
13
6
|
static description: string;
|
|
14
7
|
static strict: boolean;
|
|
@@ -21,7 +14,8 @@ export default class FingerprintCompare extends EasCommand {
|
|
|
21
14
|
static flags: {
|
|
22
15
|
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
23
16
|
'non-interactive': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
24
|
-
'build-id': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
|
|
17
|
+
'build-id': import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined>;
|
|
18
|
+
'update-id': import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined>;
|
|
25
19
|
};
|
|
26
20
|
static contextDefinition: {
|
|
27
21
|
vcsClient: import("../../commandUtils/context/VcsClientContextField").default;
|
|
@@ -5,19 +5,24 @@ const tslib_1 = require("tslib");
|
|
|
5
5
|
const eas_build_job_1 = require("@expo/eas-build-job");
|
|
6
6
|
const core_1 = require("@oclif/core");
|
|
7
7
|
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
8
|
+
const api_1 = require("../../api");
|
|
9
|
+
const queries_1 = require("../../branch/queries");
|
|
8
10
|
const EasCommand_1 = tslib_1.__importDefault(require("../../commandUtils/EasCommand"));
|
|
9
11
|
const builds_1 = require("../../commandUtils/builds");
|
|
10
12
|
const flags_1 = require("../../commandUtils/flags");
|
|
11
13
|
const generated_1 = require("../../graphql/generated");
|
|
12
14
|
const FingerprintMutation_1 = require("../../graphql/mutations/FingerprintMutation");
|
|
15
|
+
const AppQuery_1 = require("../../graphql/queries/AppQuery");
|
|
13
16
|
const BuildQuery_1 = require("../../graphql/queries/BuildQuery");
|
|
14
17
|
const FingerprintQuery_1 = require("../../graphql/queries/FingerprintQuery");
|
|
18
|
+
const UpdateQuery_1 = require("../../graphql/queries/UpdateQuery");
|
|
15
19
|
const log_1 = tslib_1.__importDefault(require("../../log"));
|
|
16
20
|
const ora_1 = require("../../ora");
|
|
17
21
|
const maybeUploadFingerprintAsync_1 = require("../../project/maybeUploadFingerprintAsync");
|
|
18
22
|
const projectUtils_1 = require("../../project/projectUtils");
|
|
19
23
|
const workflow_1 = require("../../project/workflow");
|
|
20
24
|
const prompts_1 = require("../../prompts");
|
|
25
|
+
const queries_2 = require("../../update/queries");
|
|
21
26
|
const fingerprintCli_1 = require("../../utils/fingerprintCli");
|
|
22
27
|
const fingerprintDiff_1 = require("../../utils/fingerprintDiff");
|
|
23
28
|
const formatFields_1 = tslib_1.__importDefault(require("../../utils/formatFields"));
|
|
@@ -25,6 +30,7 @@ const json_1 = require("../../utils/json");
|
|
|
25
30
|
var FingerprintOriginType;
|
|
26
31
|
(function (FingerprintOriginType) {
|
|
27
32
|
FingerprintOriginType["Build"] = "build";
|
|
33
|
+
FingerprintOriginType["Update"] = "update";
|
|
28
34
|
FingerprintOriginType["Hash"] = "hash";
|
|
29
35
|
FingerprintOriginType["Project"] = "project";
|
|
30
36
|
})(FingerprintOriginType || (FingerprintOriginType = {}));
|
|
@@ -33,9 +39,12 @@ class FingerprintCompare extends EasCommand_1.default {
|
|
|
33
39
|
static strict = false;
|
|
34
40
|
static examples = [
|
|
35
41
|
'$ eas fingerprint:compare \t # Compare fingerprints in interactive mode',
|
|
36
|
-
'$ eas fingerprint:compare
|
|
37
|
-
'$ eas fingerprint:compare
|
|
38
|
-
'$ eas fingerprint:compare --build-id
|
|
42
|
+
'$ eas fingerprint:compare <FINGERPRINT-HASH> \t # Compare fingerprint against local directory',
|
|
43
|
+
'$ eas fingerprint:compare <FINGERPRINT-HASH-1> <FINGERPRINT-HASH-2> \t # Compare provided fingerprints',
|
|
44
|
+
'$ eas fingerprint:compare --build-id <BUILD-ID> \t # Compare fingerprint from build against local directory',
|
|
45
|
+
'$ eas fingerprint:compare --build-id <BUILD-ID-1> --build-id <BUILD-ID-2>\t # Compare fingerprint from a build against another build',
|
|
46
|
+
'$ eas fingerprint:compare --build-id <BUILD-ID> --update-id <UPDATE-ID>\t # Compare fingerprint from build against fingerprint from update',
|
|
47
|
+
'$ eas fingerprint:compare <FINGERPRINT-HASH> --update-id <UPDATE-ID> \t # Compare fingerprint from update against provided fingerprint',
|
|
39
48
|
];
|
|
40
49
|
static args = [
|
|
41
50
|
{
|
|
@@ -53,6 +62,12 @@ class FingerprintCompare extends EasCommand_1.default {
|
|
|
53
62
|
'build-id': core_1.Flags.string({
|
|
54
63
|
aliases: ['buildId'],
|
|
55
64
|
description: 'Compare the fingerprint with the build with the specified ID',
|
|
65
|
+
multiple: true,
|
|
66
|
+
}),
|
|
67
|
+
'update-id': core_1.Flags.string({
|
|
68
|
+
aliases: ['updateId'],
|
|
69
|
+
description: 'Compare the fingerprint with the update with the specified ID',
|
|
70
|
+
multiple: true,
|
|
56
71
|
}),
|
|
57
72
|
...flags_1.EasNonInteractiveAndJsonFlags,
|
|
58
73
|
};
|
|
@@ -65,8 +80,9 @@ class FingerprintCompare extends EasCommand_1.default {
|
|
|
65
80
|
async runAsync() {
|
|
66
81
|
const { args, flags } = await this.parse(FingerprintCompare);
|
|
67
82
|
const { hash1, hash2 } = args;
|
|
68
|
-
const { json, 'non-interactive': nonInteractive, 'build-id':
|
|
69
|
-
const
|
|
83
|
+
const { json, 'non-interactive': nonInteractive, 'build-id': buildIds, 'update-id': updateIds, } = flags;
|
|
84
|
+
const [buildId1, buildId2] = buildIds ?? [];
|
|
85
|
+
const [updateId1, updateId2] = updateIds ?? [];
|
|
70
86
|
const { projectId, privateProjectConfig: { projectDir }, loggedIn: { graphqlClient }, vcsClient, } = await this.getContextAsync(FingerprintCompare, {
|
|
71
87
|
nonInteractive,
|
|
72
88
|
withServerSideEnvironment: null,
|
|
@@ -74,16 +90,29 @@ class FingerprintCompare extends EasCommand_1.default {
|
|
|
74
90
|
if (json) {
|
|
75
91
|
(0, json_1.enableJsonOutput)();
|
|
76
92
|
}
|
|
77
|
-
const firstFingerprintInfo = await
|
|
93
|
+
const firstFingerprintInfo = await getFingerprintInfoAsync(graphqlClient, projectDir, projectId, vcsClient, {
|
|
94
|
+
nonInteractive,
|
|
95
|
+
buildId: buildId1,
|
|
96
|
+
updateId: updateId1,
|
|
97
|
+
hash: hash1,
|
|
98
|
+
});
|
|
78
99
|
const { fingerprint: firstFingerprint, origin: firstFingerprintOrigin } = firstFingerprintInfo;
|
|
79
|
-
const
|
|
100
|
+
const isFirstFingerprintSpecifiedByFlagOrArg = hash1 || buildId1 || updateId1;
|
|
101
|
+
const isSecondFingerprintSpecifiedByFlagOrArg = hash2 || buildId2 || updateId2;
|
|
102
|
+
const secondFingerprintInfo = await getFingerprintInfoAsync(graphqlClient, projectDir, projectId, vcsClient, {
|
|
103
|
+
nonInteractive,
|
|
104
|
+
buildId: buildId2,
|
|
105
|
+
updateId: updateId2,
|
|
106
|
+
hash: hash2,
|
|
107
|
+
useProjectFingerprint: isFirstFingerprintSpecifiedByFlagOrArg && !isSecondFingerprintSpecifiedByFlagOrArg,
|
|
108
|
+
}, firstFingerprintInfo);
|
|
80
109
|
const { fingerprint: secondFingerprint, origin: secondFingerprintOrigin } = secondFingerprintInfo;
|
|
81
110
|
if (json) {
|
|
82
111
|
(0, json_1.printJsonOnlyOutput)({ fingerprint1: firstFingerprint, fingerprint2: secondFingerprint });
|
|
83
112
|
return;
|
|
84
113
|
}
|
|
85
114
|
if (firstFingerprint.hash === secondFingerprint.hash) {
|
|
86
|
-
log_1.default.log(`✅ ${capitalizeFirstLetter(prettyPrintFingerprint(firstFingerprint, firstFingerprintOrigin))} matches
|
|
115
|
+
log_1.default.log(`✅ ${capitalizeFirstLetter(prettyPrintFingerprint(firstFingerprint, firstFingerprintOrigin))} matches ${prettyPrintFingerprint(secondFingerprint, secondFingerprintOrigin)}`);
|
|
87
116
|
return;
|
|
88
117
|
}
|
|
89
118
|
else {
|
|
@@ -141,77 +170,95 @@ class FingerprintCompare extends EasCommand_1.default {
|
|
|
141
170
|
}
|
|
142
171
|
}
|
|
143
172
|
exports.default = FingerprintCompare;
|
|
144
|
-
function
|
|
145
|
-
if (
|
|
146
|
-
return
|
|
173
|
+
async function getFingerprintInfoAsync(graphqlClient, projectDir, projectId, vcsClient, { buildId, updateId, hash, useProjectFingerprint, nonInteractive, }, firstFingerprintInfo) {
|
|
174
|
+
if (hash) {
|
|
175
|
+
return await getFingerprintInfoFromHashAsync(graphqlClient, projectId, hash);
|
|
147
176
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
if (
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
let platforms;
|
|
158
|
-
const fingerprintBuilds = fingerprintFragment.builds?.edges.map(edge => edge.node) ?? [];
|
|
159
|
-
const fingerprintUpdates = fingerprintFragment.updates?.edges.map(edge => edge.node) ?? [];
|
|
160
|
-
if (fingerprintBuilds.length > 0) {
|
|
161
|
-
platforms = [fingerprintBuilds[0].platform];
|
|
162
|
-
}
|
|
163
|
-
else if (fingerprintUpdates.length > 0) {
|
|
164
|
-
platforms = [stringToAppPlatform(fingerprintUpdates[0].platform)];
|
|
177
|
+
else if (updateId) {
|
|
178
|
+
return await getFingerprintInfoFromUpdateGroupIdOrUpdateIdAsync(graphqlClient, projectId, nonInteractive, updateId);
|
|
179
|
+
}
|
|
180
|
+
else if (buildId) {
|
|
181
|
+
return await getFingerprintInfoFromBuildIdAsync(graphqlClient, buildId);
|
|
182
|
+
}
|
|
183
|
+
else if (useProjectFingerprint) {
|
|
184
|
+
if (!firstFingerprintInfo) {
|
|
185
|
+
throw new Error('First fingerprint must be provided in order to compare against the project.');
|
|
165
186
|
}
|
|
166
|
-
return
|
|
167
|
-
fingerprint,
|
|
168
|
-
platforms,
|
|
169
|
-
origin: {
|
|
170
|
-
type: FingerprintOriginType.Hash,
|
|
171
|
-
},
|
|
172
|
-
};
|
|
187
|
+
return await getFingerprintInfoFromLocalProjectAsync(graphqlClient, projectDir, projectId, vcsClient, firstFingerprintInfo);
|
|
173
188
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
189
|
+
if (nonInteractive) {
|
|
190
|
+
throw new Error('Insufficent arguments provided for fingerprint comparison in non-interactive mode');
|
|
191
|
+
}
|
|
192
|
+
return await getFingerprintInfoInteractiveAsync(graphqlClient, projectDir, projectId, vcsClient, firstFingerprintInfo);
|
|
193
|
+
}
|
|
194
|
+
async function getFingerprintInfoInteractiveAsync(graphqlClient, projectDir, projectId, vcsClient, firstFingerprintInfo) {
|
|
195
|
+
const prompt = firstFingerprintInfo
|
|
196
|
+
? 'Select the second fingerprint to compare against'
|
|
197
|
+
: 'Select a reference fingerprint for comparison';
|
|
198
|
+
const originType = await (0, prompts_1.selectAsync)(prompt, [
|
|
199
|
+
...(firstFingerprintInfo
|
|
200
|
+
? [{ title: 'Current project fingerprint', value: FingerprintOriginType.Project }]
|
|
201
|
+
: []),
|
|
202
|
+
{ title: 'Build fingerprint', value: FingerprintOriginType.Build },
|
|
203
|
+
{ title: 'Update fingerprint', value: FingerprintOriginType.Update },
|
|
204
|
+
{ title: 'Enter a fingerprint hash manually', value: FingerprintOriginType.Hash },
|
|
205
|
+
]);
|
|
206
|
+
if (originType === FingerprintOriginType.Project) {
|
|
207
|
+
if (!firstFingerprintInfo) {
|
|
208
|
+
throw new Error('First fingerprint must be provided in order to compare against the project.');
|
|
178
209
|
}
|
|
210
|
+
return await getFingerprintInfoFromLocalProjectAsync(graphqlClient, projectDir, projectId, vcsClient, firstFingerprintInfo);
|
|
211
|
+
}
|
|
212
|
+
else if (originType === FingerprintOriginType.Build) {
|
|
179
213
|
const displayName = await (0, projectUtils_1.getDisplayNameForProjectIdAsync)(graphqlClient, projectId);
|
|
180
|
-
buildId = await selectBuildToCompareAsync(graphqlClient, projectId, displayName, {
|
|
214
|
+
const buildId = await selectBuildToCompareAsync(graphqlClient, projectId, displayName, {
|
|
181
215
|
filters: { hasFingerprint: true },
|
|
182
216
|
});
|
|
183
217
|
if (!buildId) {
|
|
184
218
|
throw new Error('Must select build with fingerprint for comparison.');
|
|
185
219
|
}
|
|
220
|
+
return await getFingerprintInfoFromBuildIdAsync(graphqlClient, buildId);
|
|
221
|
+
}
|
|
222
|
+
else if (originType === FingerprintOriginType.Update) {
|
|
223
|
+
const selectedBranch = await (0, queries_1.selectBranchOnAppAsync)(graphqlClient, {
|
|
224
|
+
projectId,
|
|
225
|
+
promptTitle: 'On which branch would you like search for an update?',
|
|
226
|
+
displayTextForListItem: updateBranch => ({
|
|
227
|
+
title: updateBranch.name,
|
|
228
|
+
}),
|
|
229
|
+
paginatedQueryOptions: {
|
|
230
|
+
json: false,
|
|
231
|
+
nonInteractive: false,
|
|
232
|
+
offset: 0,
|
|
233
|
+
},
|
|
234
|
+
});
|
|
235
|
+
const selectedUpdateGroup = await (0, queries_2.selectUpdateGroupOnBranchAsync)(graphqlClient, {
|
|
236
|
+
projectId,
|
|
237
|
+
branchName: selectedBranch.name,
|
|
238
|
+
paginatedQueryOptions: {
|
|
239
|
+
json: false,
|
|
240
|
+
nonInteractive: false,
|
|
241
|
+
offset: 0,
|
|
242
|
+
},
|
|
243
|
+
});
|
|
244
|
+
const updateGroupId = selectedUpdateGroup[0].group;
|
|
245
|
+
return await getFingerprintInfoFromUpdateGroupIdOrUpdateIdAsync(graphqlClient, projectId, false, updateGroupId);
|
|
246
|
+
}
|
|
247
|
+
else if (originType === FingerprintOriginType.Hash) {
|
|
248
|
+
const { hash } = await (0, prompts_1.promptAsync)({
|
|
249
|
+
type: 'text',
|
|
250
|
+
name: 'hash',
|
|
251
|
+
message: 'Provide the fingerprint hash',
|
|
252
|
+
validate: (value) => !!value.trim(),
|
|
253
|
+
hint: '0000000000000000000000000000000000000000',
|
|
254
|
+
});
|
|
255
|
+
return await getFingerprintInfoFromHashAsync(graphqlClient, projectId, hash);
|
|
186
256
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
if (!buildWithFingerprint.fingerprint) {
|
|
190
|
-
throw new Error(`Fingerprint for build ${buildId} was not computed.`);
|
|
191
|
-
}
|
|
192
|
-
else if (!buildWithFingerprint.fingerprint.debugInfoUrl) {
|
|
193
|
-
throw new Error(`Fingerprint source for build ${buildId} was not computed.`);
|
|
257
|
+
else {
|
|
258
|
+
throw new Error(`Unsupported fingerprint origin type: ${originType}`);
|
|
194
259
|
}
|
|
195
|
-
return {
|
|
196
|
-
fingerprint: await getFingerprintFromFingerprintFragmentAsync(buildWithFingerprint.fingerprint),
|
|
197
|
-
platforms: [buildWithFingerprint.platform],
|
|
198
|
-
origin: {
|
|
199
|
-
type: FingerprintOriginType.Build,
|
|
200
|
-
build: buildWithFingerprint,
|
|
201
|
-
},
|
|
202
|
-
};
|
|
203
260
|
}
|
|
204
|
-
async function
|
|
205
|
-
if (hash2) {
|
|
206
|
-
const fingerprintFragment = await getFingerprintFragmentFromHashAsync(graphqlClient, projectId, hash2);
|
|
207
|
-
if (!fingerprintFragment) {
|
|
208
|
-
throw new Error(`Fingerprint with hash ${hash2} was not uploaded.`);
|
|
209
|
-
}
|
|
210
|
-
return {
|
|
211
|
-
fingerprint: await getFingerprintFromFingerprintFragmentAsync(fingerprintFragment),
|
|
212
|
-
origin: { type: FingerprintOriginType.Hash },
|
|
213
|
-
};
|
|
214
|
-
}
|
|
261
|
+
async function getFingerprintInfoFromLocalProjectAsync(graphqlClient, projectDir, projectId, vcsClient, firstFingerprintInfo) {
|
|
215
262
|
const firstFingerprintPlatforms = firstFingerprintInfo.platforms;
|
|
216
263
|
if (!firstFingerprintPlatforms) {
|
|
217
264
|
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.`);
|
|
@@ -241,6 +288,96 @@ async function getSecondFingerprintInfoAsync(graphqlClient, projectDir, projectI
|
|
|
241
288
|
});
|
|
242
289
|
return { fingerprint: projectFingerprint, origin: { type: FingerprintOriginType.Project } };
|
|
243
290
|
}
|
|
291
|
+
async function getFingerprintFromUpdateFragmentAsync(updateWithFingerprint) {
|
|
292
|
+
if (!updateWithFingerprint.fingerprint) {
|
|
293
|
+
throw new Error(`Fingerprint for update ${updateWithFingerprint.id} was not computed.`);
|
|
294
|
+
}
|
|
295
|
+
else if (!updateWithFingerprint.fingerprint.debugInfoUrl) {
|
|
296
|
+
throw new Error(`Fingerprint source for update ${updateWithFingerprint.id} was not computed.`);
|
|
297
|
+
}
|
|
298
|
+
return {
|
|
299
|
+
fingerprint: await getFingerprintFromFingerprintFragmentAsync(updateWithFingerprint.fingerprint),
|
|
300
|
+
platforms: [stringToAppPlatform(updateWithFingerprint.platform)],
|
|
301
|
+
origin: {
|
|
302
|
+
type: FingerprintOriginType.Update,
|
|
303
|
+
update: updateWithFingerprint,
|
|
304
|
+
},
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
async function getFingerprintInfoFromHashAsync(graphqlClient, projectId, hash) {
|
|
308
|
+
const fingerprintFragment = await getFingerprintFragmentFromHashAsync(graphqlClient, projectId, hash);
|
|
309
|
+
const fingerprint = await getFingerprintFromFingerprintFragmentAsync(fingerprintFragment);
|
|
310
|
+
let platforms;
|
|
311
|
+
const fingerprintBuilds = fingerprintFragment.builds?.edges.map(edge => edge.node) ?? [];
|
|
312
|
+
const fingerprintUpdates = fingerprintFragment.updates?.edges.map(edge => edge.node) ?? [];
|
|
313
|
+
if (fingerprintBuilds.length > 0) {
|
|
314
|
+
platforms = [fingerprintBuilds[0].platform];
|
|
315
|
+
}
|
|
316
|
+
else if (fingerprintUpdates.length > 0) {
|
|
317
|
+
platforms = [stringToAppPlatform(fingerprintUpdates[0].platform)];
|
|
318
|
+
}
|
|
319
|
+
return {
|
|
320
|
+
fingerprint,
|
|
321
|
+
platforms,
|
|
322
|
+
origin: {
|
|
323
|
+
type: FingerprintOriginType.Hash,
|
|
324
|
+
},
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
async function getFingerprintInfoFromUpdateGroupIdOrUpdateIdAsync(graphqlClient, projectId, nonInteractive, updateGroupIdOrUpdateId) {
|
|
328
|
+
// Some people may pass in update group id instead of update id, so add interactive support for that
|
|
329
|
+
try {
|
|
330
|
+
const maybeUpdateGroupId = updateGroupIdOrUpdateId;
|
|
331
|
+
const updateGroup = await UpdateQuery_1.UpdateQuery.viewUpdateGroupAsync(graphqlClient, {
|
|
332
|
+
groupId: maybeUpdateGroupId,
|
|
333
|
+
});
|
|
334
|
+
if (updateGroup.length === 1) {
|
|
335
|
+
const update = updateGroup[0];
|
|
336
|
+
return await getFingerprintFromUpdateFragmentAsync(update);
|
|
337
|
+
}
|
|
338
|
+
if (nonInteractive) {
|
|
339
|
+
const [accountName, project] = await Promise.all([
|
|
340
|
+
(await (0, projectUtils_1.getOwnerAccountForProjectIdAsync)(graphqlClient, projectId)).name,
|
|
341
|
+
AppQuery_1.AppQuery.byIdAsync(graphqlClient, projectId),
|
|
342
|
+
]);
|
|
343
|
+
const updateUrl = (0, api_1.getExpoWebsiteBaseUrl)() +
|
|
344
|
+
`/accounts/${accountName}/projects/${project.name}/updates/${maybeUpdateGroupId}`;
|
|
345
|
+
throw new Error(`Please pass in your update ID from ${updateUrl} or use interactive mode to select the update ID.`);
|
|
346
|
+
}
|
|
347
|
+
const update = await (0, prompts_1.selectAsync)('Select a platform to compute the fingerprint from', updateGroup.map(update => ({
|
|
348
|
+
title: update.platform,
|
|
349
|
+
value: update,
|
|
350
|
+
})));
|
|
351
|
+
return await getFingerprintFromUpdateFragmentAsync(update);
|
|
352
|
+
}
|
|
353
|
+
catch (error) {
|
|
354
|
+
if (!error?.message.includes('Could not find any updates with group ID')) {
|
|
355
|
+
throw error;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
const updateId = updateGroupIdOrUpdateId;
|
|
359
|
+
const updateWithFingerprint = await UpdateQuery_1.UpdateQuery.viewByUpdateAsync(graphqlClient, {
|
|
360
|
+
updateId,
|
|
361
|
+
});
|
|
362
|
+
return await getFingerprintFromUpdateFragmentAsync(updateWithFingerprint);
|
|
363
|
+
}
|
|
364
|
+
async function getFingerprintInfoFromBuildIdAsync(graphqlClient, buildId) {
|
|
365
|
+
const buildWithFingerprint = await BuildQuery_1.BuildQuery.withFingerprintByIdAsync(graphqlClient, buildId);
|
|
366
|
+
if (!buildWithFingerprint.fingerprint) {
|
|
367
|
+
throw new Error(`Fingerprint for build ${buildId} was not computed.`);
|
|
368
|
+
}
|
|
369
|
+
else if (!buildWithFingerprint.fingerprint.debugInfoUrl) {
|
|
370
|
+
throw new Error(`Fingerprint source for build ${buildId} was not computed.`);
|
|
371
|
+
}
|
|
372
|
+
return {
|
|
373
|
+
fingerprint: await getFingerprintFromFingerprintFragmentAsync(buildWithFingerprint.fingerprint),
|
|
374
|
+
platforms: [buildWithFingerprint.platform],
|
|
375
|
+
origin: {
|
|
376
|
+
type: FingerprintOriginType.Build,
|
|
377
|
+
build: buildWithFingerprint,
|
|
378
|
+
},
|
|
379
|
+
};
|
|
380
|
+
}
|
|
244
381
|
async function getFingerprintFragmentFromHashAsync(graphqlClient, projectId, hash) {
|
|
245
382
|
const fingerprint = await FingerprintQuery_1.FingerprintQuery.byHashAsync(graphqlClient, {
|
|
246
383
|
appId: projectId,
|
|
@@ -412,6 +549,21 @@ function printContentsDiff(contents1, contents2) {
|
|
|
412
549
|
: stringifiedContents2;
|
|
413
550
|
(0, fingerprintDiff_1.abridgedDiff)(prettifiedContents1, prettifiedContents2, 0);
|
|
414
551
|
}
|
|
552
|
+
function prettyPrintFingerprint(fingerprint, origin) {
|
|
553
|
+
if (origin.type === FingerprintOriginType.Project) {
|
|
554
|
+
return `fingerprint ${fingerprint.hash} from local directory`;
|
|
555
|
+
}
|
|
556
|
+
else if (origin.type === FingerprintOriginType.Update) {
|
|
557
|
+
return `fingerprint ${fingerprint.hash} from ${origin.update?.platform ? stringToAppPlatform(origin.update?.platform) : ''} ${origin.type}`;
|
|
558
|
+
}
|
|
559
|
+
else if (origin.type === FingerprintOriginType.Build) {
|
|
560
|
+
return `fingerprint ${fingerprint.hash} from ${origin.build?.platform} ${origin.type}`;
|
|
561
|
+
}
|
|
562
|
+
return `fingerprint ${fingerprint.hash}`;
|
|
563
|
+
}
|
|
564
|
+
function capitalizeFirstLetter(string) {
|
|
565
|
+
return string.charAt(0).toUpperCase() + string.slice(1);
|
|
566
|
+
}
|
|
415
567
|
function isJSON(str) {
|
|
416
568
|
try {
|
|
417
569
|
JSON.parse(str);
|
|
@@ -108,7 +108,10 @@ class Onboarding extends EasCommand_1.default {
|
|
|
108
108
|
targetProjectDir: initialTargetProjectDirectory,
|
|
109
109
|
cloneMethod,
|
|
110
110
|
});
|
|
111
|
-
const vcsClient = new git_2.default(
|
|
111
|
+
const vcsClient = new git_2.default({
|
|
112
|
+
maybeCwdOverride: finalTargetProjectDirectory,
|
|
113
|
+
requireCommit: false,
|
|
114
|
+
});
|
|
112
115
|
if (!app.githubRepository) {
|
|
113
116
|
await fs_extra_1.default.remove(path_1.default.join(finalTargetProjectDirectory, '.git'));
|
|
114
117
|
await (0, runCommand_1.runCommandAsync)({
|
|
@@ -13,8 +13,7 @@ const AndroidSubmitCommand_1 = tslib_1.__importDefault(require("../../submit/and
|
|
|
13
13
|
const context_1 = require("../../submit/context");
|
|
14
14
|
const IosSubmitCommand_1 = tslib_1.__importDefault(require("../../submit/ios/IosSubmitCommand"));
|
|
15
15
|
const json_1 = require("../../utils/json");
|
|
16
|
-
const
|
|
17
|
-
const noVcs_1 = tslib_1.__importDefault(require("../../vcs/clients/noVcs"));
|
|
16
|
+
const git_1 = tslib_1.__importDefault(require("../../vcs/clients/git"));
|
|
18
17
|
/**
|
|
19
18
|
* This command will be run on the EAS workers.
|
|
20
19
|
* This command resolves credentials and other
|
|
@@ -49,9 +48,14 @@ class SubmitInternal extends EasCommand_1.default {
|
|
|
49
48
|
(0, json_1.enableJsonOutput)();
|
|
50
49
|
const { loggedIn: { actor, graphqlClient }, privateProjectConfig: { exp, projectId, projectDir }, analytics, vcsClient, } = await this.getContextAsync(SubmitInternal, {
|
|
51
50
|
nonInteractive: true,
|
|
52
|
-
vcsClientOverride: process.env.EAS_NO_VCS ? new noVcs_1.default() : new gitNoCommit_1.default(),
|
|
53
51
|
withServerSideEnvironment: null,
|
|
54
52
|
});
|
|
53
|
+
if (vcsClient instanceof git_1.default) {
|
|
54
|
+
// `build:internal` is run on EAS workers and the repo may have been changed
|
|
55
|
+
// by pre-install hooks or other scripts. We don't want to require committing changes
|
|
56
|
+
// to continue the build.
|
|
57
|
+
vcsClient.requireCommit = false;
|
|
58
|
+
}
|
|
55
59
|
const submissionProfile = await eas_json_1.EasJsonUtils.getSubmitProfileAsync(eas_json_1.EasJsonAccessor.fromProjectPath(projectDir), flags.platform, flags.profile);
|
|
56
60
|
const ctx = await (0, context_1.createSubmissionContextAsync)({
|
|
57
61
|
platform: flags.platform,
|
|
@@ -11705,6 +11705,7 @@ export type UpdatePublishMutation = {
|
|
|
11705
11705
|
__typename?: 'Fingerprint';
|
|
11706
11706
|
id: string;
|
|
11707
11707
|
hash: string;
|
|
11708
|
+
debugInfoUrl?: string | null;
|
|
11708
11709
|
source?: {
|
|
11709
11710
|
__typename?: 'FingerprintSource';
|
|
11710
11711
|
type: FingerprintSourceType;
|
|
@@ -11790,6 +11791,7 @@ export type SetRolloutPercentageMutation = {
|
|
|
11790
11791
|
__typename?: 'Fingerprint';
|
|
11791
11792
|
id: string;
|
|
11792
11793
|
hash: string;
|
|
11794
|
+
debugInfoUrl?: string | null;
|
|
11793
11795
|
source?: {
|
|
11794
11796
|
__typename?: 'FingerprintSource';
|
|
11795
11797
|
type: FingerprintSourceType;
|
|
@@ -12260,6 +12262,7 @@ export type BranchesByAppQuery = {
|
|
|
12260
12262
|
__typename?: 'Fingerprint';
|
|
12261
12263
|
id: string;
|
|
12262
12264
|
hash: string;
|
|
12265
|
+
debugInfoUrl?: string | null;
|
|
12263
12266
|
source?: {
|
|
12264
12267
|
__typename?: 'FingerprintSource';
|
|
12265
12268
|
type: FingerprintSourceType;
|
|
@@ -12373,6 +12376,7 @@ export type ViewBranchesOnUpdateChannelQuery = {
|
|
|
12373
12376
|
__typename?: 'Fingerprint';
|
|
12374
12377
|
id: string;
|
|
12375
12378
|
hash: string;
|
|
12379
|
+
debugInfoUrl?: string | null;
|
|
12376
12380
|
source?: {
|
|
12377
12381
|
__typename?: 'FingerprintSource';
|
|
12378
12382
|
type: FingerprintSourceType;
|
|
@@ -12833,6 +12837,7 @@ export type ViewUpdateChannelOnAppQuery = {
|
|
|
12833
12837
|
__typename?: 'Fingerprint';
|
|
12834
12838
|
id: string;
|
|
12835
12839
|
hash: string;
|
|
12840
|
+
debugInfoUrl?: string | null;
|
|
12836
12841
|
source?: {
|
|
12837
12842
|
__typename?: 'FingerprintSource';
|
|
12838
12843
|
type: FingerprintSourceType;
|
|
@@ -12915,6 +12920,7 @@ export type ViewUpdateChannelsOnAppQuery = {
|
|
|
12915
12920
|
__typename?: 'Fingerprint';
|
|
12916
12921
|
id: string;
|
|
12917
12922
|
hash: string;
|
|
12923
|
+
debugInfoUrl?: string | null;
|
|
12918
12924
|
source?: {
|
|
12919
12925
|
__typename?: 'FingerprintSource';
|
|
12920
12926
|
type: FingerprintSourceType;
|
|
@@ -13434,6 +13440,7 @@ export type ViewUpdatesByGroupQuery = {
|
|
|
13434
13440
|
__typename?: 'Fingerprint';
|
|
13435
13441
|
id: string;
|
|
13436
13442
|
hash: string;
|
|
13443
|
+
debugInfoUrl?: string | null;
|
|
13437
13444
|
source?: {
|
|
13438
13445
|
__typename?: 'FingerprintSource';
|
|
13439
13446
|
type: FingerprintSourceType;
|
|
@@ -13505,6 +13512,7 @@ export type ViewUpdateGroupsOnBranchQuery = {
|
|
|
13505
13512
|
__typename?: 'Fingerprint';
|
|
13506
13513
|
id: string;
|
|
13507
13514
|
hash: string;
|
|
13515
|
+
debugInfoUrl?: string | null;
|
|
13508
13516
|
source?: {
|
|
13509
13517
|
__typename?: 'FingerprintSource';
|
|
13510
13518
|
type: FingerprintSourceType;
|
|
@@ -13575,6 +13583,7 @@ export type ViewUpdateGroupsOnAppQuery = {
|
|
|
13575
13583
|
__typename?: 'Fingerprint';
|
|
13576
13584
|
id: string;
|
|
13577
13585
|
hash: string;
|
|
13586
|
+
debugInfoUrl?: string | null;
|
|
13578
13587
|
source?: {
|
|
13579
13588
|
__typename?: 'FingerprintSource';
|
|
13580
13589
|
type: FingerprintSourceType;
|
|
@@ -13586,6 +13595,69 @@ export type ViewUpdateGroupsOnAppQuery = {
|
|
|
13586
13595
|
};
|
|
13587
13596
|
};
|
|
13588
13597
|
};
|
|
13598
|
+
export type UpdateByIdQueryVariables = Exact<{
|
|
13599
|
+
updateId: Scalars['ID']['input'];
|
|
13600
|
+
}>;
|
|
13601
|
+
export type UpdateByIdQuery = {
|
|
13602
|
+
__typename?: 'RootQuery';
|
|
13603
|
+
updates: {
|
|
13604
|
+
__typename?: 'UpdateQuery';
|
|
13605
|
+
byId: {
|
|
13606
|
+
__typename?: 'Update';
|
|
13607
|
+
id: string;
|
|
13608
|
+
group: string;
|
|
13609
|
+
message?: string | null;
|
|
13610
|
+
createdAt: any;
|
|
13611
|
+
runtimeVersion: string;
|
|
13612
|
+
platform: string;
|
|
13613
|
+
manifestFragment: string;
|
|
13614
|
+
isRollBackToEmbedded: boolean;
|
|
13615
|
+
manifestPermalink: string;
|
|
13616
|
+
gitCommitHash?: string | null;
|
|
13617
|
+
rolloutPercentage?: number | null;
|
|
13618
|
+
actor?: {
|
|
13619
|
+
__typename: 'Robot';
|
|
13620
|
+
firstName?: string | null;
|
|
13621
|
+
id: string;
|
|
13622
|
+
} | {
|
|
13623
|
+
__typename: 'SSOUser';
|
|
13624
|
+
username: string;
|
|
13625
|
+
id: string;
|
|
13626
|
+
} | {
|
|
13627
|
+
__typename: 'User';
|
|
13628
|
+
username: string;
|
|
13629
|
+
id: string;
|
|
13630
|
+
} | null;
|
|
13631
|
+
branch: {
|
|
13632
|
+
__typename?: 'UpdateBranch';
|
|
13633
|
+
id: string;
|
|
13634
|
+
name: string;
|
|
13635
|
+
};
|
|
13636
|
+
codeSigningInfo?: {
|
|
13637
|
+
__typename?: 'CodeSigningInfo';
|
|
13638
|
+
keyid: string;
|
|
13639
|
+
sig: string;
|
|
13640
|
+
alg: string;
|
|
13641
|
+
} | null;
|
|
13642
|
+
rolloutControlUpdate?: {
|
|
13643
|
+
__typename?: 'Update';
|
|
13644
|
+
id: string;
|
|
13645
|
+
} | null;
|
|
13646
|
+
fingerprint?: {
|
|
13647
|
+
__typename?: 'Fingerprint';
|
|
13648
|
+
id: string;
|
|
13649
|
+
hash: string;
|
|
13650
|
+
debugInfoUrl?: string | null;
|
|
13651
|
+
source?: {
|
|
13652
|
+
__typename?: 'FingerprintSource';
|
|
13653
|
+
type: FingerprintSourceType;
|
|
13654
|
+
bucketKey: string;
|
|
13655
|
+
isDebugFingerprint?: boolean | null;
|
|
13656
|
+
} | null;
|
|
13657
|
+
} | null;
|
|
13658
|
+
};
|
|
13659
|
+
};
|
|
13660
|
+
};
|
|
13589
13661
|
export type CurrentUserQueryVariables = Exact<{
|
|
13590
13662
|
[key: string]: never;
|
|
13591
13663
|
}>;
|
|
@@ -14311,6 +14383,7 @@ export type UpdateFragment = {
|
|
|
14311
14383
|
__typename?: 'Fingerprint';
|
|
14312
14384
|
id: string;
|
|
14313
14385
|
hash: string;
|
|
14386
|
+
debugInfoUrl?: string | null;
|
|
14314
14387
|
source?: {
|
|
14315
14388
|
__typename?: 'FingerprintSource';
|
|
14316
14389
|
type: FingerprintSourceType;
|
|
@@ -14368,6 +14441,7 @@ export type UpdateBranchFragment = {
|
|
|
14368
14441
|
__typename?: 'Fingerprint';
|
|
14369
14442
|
id: string;
|
|
14370
14443
|
hash: string;
|
|
14444
|
+
debugInfoUrl?: string | null;
|
|
14371
14445
|
source?: {
|
|
14372
14446
|
__typename?: 'FingerprintSource';
|
|
14373
14447
|
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
|
};
|