@ship-et/buildatlas-cli 0.14.0 → 0.14.2-beta
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/dist/commands/migrate/build-numbers.d.ts +2 -1
- package/dist/commands/migrate/build-numbers.d.ts.map +1 -1
- package/dist/commands/migrate/build-numbers.js +26 -6
- package/dist/commands/migrate/build-numbers.js.map +1 -1
- package/dist/commands/migrate/credentials.d.ts +17 -15
- package/dist/commands/migrate/credentials.d.ts.map +1 -1
- package/dist/commands/migrate/credentials.js +110 -45
- package/dist/commands/migrate/credentials.js.map +1 -1
- package/dist/commands/migrate/eas-client.d.ts +57 -5
- package/dist/commands/migrate/eas-client.d.ts.map +1 -1
- package/dist/commands/migrate/eas-client.js +112 -16
- package/dist/commands/migrate/eas-client.js.map +1 -1
- package/dist/commands/migrate/env.d.ts +24 -0
- package/dist/commands/migrate/env.d.ts.map +1 -0
- package/dist/commands/migrate/env.js +99 -0
- package/dist/commands/migrate/env.js.map +1 -0
- package/dist/commands/migrate/index.d.ts.map +1 -1
- package/dist/commands/migrate/index.js +146 -58
- package/dist/commands/migrate/index.js.map +1 -1
- package/dist/commands/migrate/report.d.ts +26 -0
- package/dist/commands/migrate/report.d.ts.map +1 -0
- package/dist/commands/migrate/report.js +84 -0
- package/dist/commands/migrate/report.js.map +1 -0
- package/dist/prompt.d.ts +16 -0
- package/dist/prompt.d.ts.map +1 -1
- package/dist/prompt.js +143 -0
- package/dist/prompt.js.map +1 -1
- package/dist/spinner.d.ts.map +1 -1
- package/dist/spinner.js +3 -1
- package/dist/spinner.js.map +1 -1
- package/package.json +1 -1
|
@@ -25,7 +25,10 @@ async function expoGraphQL(auth, query, variables) {
|
|
|
25
25
|
});
|
|
26
26
|
}
|
|
27
27
|
catch (err) {
|
|
28
|
-
|
|
28
|
+
// undici's message is always "fetch failed"; the cause says which kind.
|
|
29
|
+
const cause = err.cause;
|
|
30
|
+
const why = cause?.code ?? cause?.message ?? err.message;
|
|
31
|
+
throw new Error(`Could not reach api.expo.dev (${why}). Check the connection and run it again.`);
|
|
29
32
|
}
|
|
30
33
|
if (res.status === 401 || res.status === 403) {
|
|
31
34
|
throw new Error(auth.kind === 'token' ? 'Expo rejected this token.' : 'Expo rejected this session.');
|
|
@@ -83,19 +86,40 @@ export async function getAppIdentifiers(auth, appId) {
|
|
|
83
86
|
}
|
|
84
87
|
}`, { appId });
|
|
85
88
|
return {
|
|
86
|
-
|
|
89
|
+
// Several entries when the app has extensions; the first is not reliably the app itself.
|
|
90
|
+
bundleIdentifier: mainBundleIdentifier(app.byId.iosAppCredentials.map((c) => c.appleAppIdentifier.bundleIdentifier)),
|
|
87
91
|
androidPackage: app.byId.androidAppCredentials.find((c) => c.applicationIdentifier)?.applicationIdentifier ?? undefined,
|
|
88
92
|
};
|
|
89
93
|
}
|
|
90
94
|
/**
|
|
91
|
-
*
|
|
92
|
-
*
|
|
95
|
+
* EAS hands `.p8` keys back as the file's PEM text, while the vault stores
|
|
96
|
+
* every key file base64-encoded, as an uploaded file would be. Passed through
|
|
97
|
+
* when it is already base64, in case EAS ever changes which one it returns.
|
|
98
|
+
*/
|
|
99
|
+
function p8ToBase64(keyP8) {
|
|
100
|
+
return keyP8.includes('-----BEGIN') ? Buffer.from(keyP8, 'utf8').toString('base64') : keyP8.replace(/\s+/g, '');
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* The main app's bundle id out of a set that may include extensions — the one
|
|
104
|
+
* every other id extends (`com.app` for `com.app.OneSignalNotificationServiceExtension`).
|
|
105
|
+
* Falls back to the first when nothing nests, which is the single-target case.
|
|
106
|
+
*/
|
|
107
|
+
export function mainBundleIdentifier(ids) {
|
|
108
|
+
return ids.find((id) => ids.every((other) => other === id || other.startsWith(`${id}.`))) ?? ids[0];
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* The actual signing material EAS holds for this app — a distribution cert and
|
|
112
|
+
* provisioning profile per iOS target, a keystore for Android, and an APNs
|
|
93
113
|
* push key if one was ever generated for push notifications — in the same
|
|
94
114
|
* base64 shape `buildatlas credentials add` already expects (`ios_dist_cert`,
|
|
95
115
|
* `ios_provisioning_profile`, `android_keystore`, `ios_push_key`), so it can be
|
|
96
116
|
* forwarded as-is.
|
|
97
117
|
*
|
|
98
|
-
*
|
|
118
|
+
* Every iOS target, not just the first: an app with a notification service
|
|
119
|
+
* extension (OneSignal's, for one) has its own bundle id and its own profile on
|
|
120
|
+
* EAS, and an archive with a target missing its profile fails to export.
|
|
121
|
+
*
|
|
122
|
+
* Picks the App Store build credentials per target (ad-hoc/enterprise/development
|
|
99
123
|
* profiles are for internal testing, not what a migrated app should ship with)
|
|
100
124
|
* and whichever Android keystore is marked default. Omits a platform, or the
|
|
101
125
|
* push key, entirely rather than guessing when EAS has never generated one.
|
|
@@ -111,6 +135,7 @@ export async function getEasCredentials(auth, appId) {
|
|
|
111
135
|
byId(appId: $appId) {
|
|
112
136
|
id
|
|
113
137
|
iosAppCredentials {
|
|
138
|
+
appleAppIdentifier { bundleIdentifier }
|
|
114
139
|
pushKey { keyIdentifier keyP8 }
|
|
115
140
|
iosAppBuildCredentialsList {
|
|
116
141
|
iosDistributionType
|
|
@@ -127,21 +152,26 @@ export async function getEasCredentials(auth, appId) {
|
|
|
127
152
|
}
|
|
128
153
|
}
|
|
129
154
|
}`, { appId });
|
|
130
|
-
const
|
|
131
|
-
const
|
|
132
|
-
|
|
155
|
+
const ios = [];
|
|
156
|
+
for (const target of app.byId.iosAppCredentials) {
|
|
157
|
+
const list = target.iosAppBuildCredentialsList;
|
|
158
|
+
const entry = list.find((c) => c.iosDistributionType === 'APP_STORE' && c.distributionCertificate?.certificateP12) ??
|
|
159
|
+
list.find((c) => c.distributionCertificate?.certificateP12);
|
|
160
|
+
if (!entry?.distributionCertificate?.certificateP12)
|
|
161
|
+
continue;
|
|
162
|
+
ios.push({
|
|
163
|
+
bundleIdentifier: target.appleAppIdentifier.bundleIdentifier,
|
|
164
|
+
p12Base64: entry.distributionCertificate.certificateP12,
|
|
165
|
+
password: entry.distributionCertificate.certificatePassword ?? undefined,
|
|
166
|
+
profileBase64: entry.provisioningProfile?.provisioningProfile ?? undefined,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
133
169
|
const androidBuildCredentials = app.byId.androidAppCredentials.flatMap((c) => c.androidAppBuildCredentialsList);
|
|
134
170
|
const androidEntry = androidBuildCredentials.find((c) => c.isDefault && c.androidKeystore) ??
|
|
135
171
|
androidBuildCredentials.find((c) => c.androidKeystore);
|
|
136
172
|
const pushKeyEntry = app.byId.iosAppCredentials.find((c) => c.pushKey)?.pushKey;
|
|
137
173
|
return {
|
|
138
|
-
ios
|
|
139
|
-
? {
|
|
140
|
-
p12Base64: iosEntry.distributionCertificate.certificateP12,
|
|
141
|
-
password: iosEntry.distributionCertificate.certificatePassword ?? undefined,
|
|
142
|
-
profileBase64: iosEntry.provisioningProfile?.provisioningProfile ?? undefined,
|
|
143
|
-
}
|
|
144
|
-
: undefined,
|
|
174
|
+
ios,
|
|
145
175
|
android: androidEntry?.androidKeystore
|
|
146
176
|
? {
|
|
147
177
|
keystoreBase64: androidEntry.androidKeystore.keystore,
|
|
@@ -151,10 +181,76 @@ export async function getEasCredentials(auth, appId) {
|
|
|
151
181
|
}
|
|
152
182
|
: undefined,
|
|
153
183
|
iosPushKey: pushKeyEntry
|
|
154
|
-
? { keyId: pushKeyEntry.keyIdentifier, p8Base64: pushKeyEntry.keyP8 }
|
|
184
|
+
? { keyId: pushKeyEntry.keyIdentifier, p8Base64: p8ToBase64(pushKeyEntry.keyP8) }
|
|
155
185
|
: undefined,
|
|
156
186
|
};
|
|
157
187
|
}
|
|
188
|
+
/**
|
|
189
|
+
* The keys EAS keeps for submitting and push, separate from the signing query
|
|
190
|
+
* above: reading raw key material needs a higher role on the Expo account, and
|
|
191
|
+
* a permission error here should not cost the signing credentials too.
|
|
192
|
+
*/
|
|
193
|
+
export async function getEasServiceKeys(auth, appId) {
|
|
194
|
+
const { app } = await expoGraphQL(auth, `query AppServiceKeys($appId: String!) {
|
|
195
|
+
app {
|
|
196
|
+
byId(appId: $appId) {
|
|
197
|
+
id
|
|
198
|
+
iosAppCredentials {
|
|
199
|
+
appStoreConnectApiKeyForSubmissions { keyIdentifier issuerIdentifier keyP8 }
|
|
200
|
+
}
|
|
201
|
+
androidAppCredentials {
|
|
202
|
+
googleServiceAccountKeyForSubmissions { keyJson }
|
|
203
|
+
googleServiceAccountKeyForFcmV1 { projectIdentifier clientEmail }
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}`, { appId });
|
|
208
|
+
const asc = app.byId.iosAppCredentials.find((c) => c.appStoreConnectApiKeyForSubmissions)
|
|
209
|
+
?.appStoreConnectApiKeyForSubmissions;
|
|
210
|
+
const play = app.byId.androidAppCredentials.find((c) => c.googleServiceAccountKeyForSubmissions)
|
|
211
|
+
?.googleServiceAccountKeyForSubmissions;
|
|
212
|
+
const fcm = app.byId.androidAppCredentials.find((c) => c.googleServiceAccountKeyForFcmV1)
|
|
213
|
+
?.googleServiceAccountKeyForFcmV1;
|
|
214
|
+
return {
|
|
215
|
+
ascApiKey: asc
|
|
216
|
+
? {
|
|
217
|
+
keyId: asc.keyIdentifier,
|
|
218
|
+
issuerId: asc.issuerIdentifier,
|
|
219
|
+
p8Base64: p8ToBase64(asc.keyP8),
|
|
220
|
+
}
|
|
221
|
+
: undefined,
|
|
222
|
+
playServiceAccountJson: play?.keyJson,
|
|
223
|
+
fcmV1: fcm ? { projectId: fcm.projectIdentifier, clientEmail: fcm.clientEmail } : undefined,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* The app's EAS environment variables across every environment, with
|
|
228
|
+
* `SENSITIVE` values included (what `eas env:pull` reads). One variable may
|
|
229
|
+
* appear several times with different values — one record per environment.
|
|
230
|
+
*/
|
|
231
|
+
export async function getEasEnvVars(auth, appId) {
|
|
232
|
+
const { app } = await expoGraphQL(auth, `query AppEnvironmentVariables($appId: String!) {
|
|
233
|
+
app {
|
|
234
|
+
byId(appId: $appId) {
|
|
235
|
+
id
|
|
236
|
+
environmentVariablesIncludingSensitive {
|
|
237
|
+
id
|
|
238
|
+
name
|
|
239
|
+
value
|
|
240
|
+
environments
|
|
241
|
+
visibility
|
|
242
|
+
type
|
|
243
|
+
fileName
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}`, { appId });
|
|
248
|
+
return app.byId.environmentVariablesIncludingSensitive.map((v) => ({
|
|
249
|
+
...v,
|
|
250
|
+
// Older projects report the built-in environments upper-case; profiles are lower-case.
|
|
251
|
+
environments: (v.environments ?? []).map((e) => e.toLowerCase()),
|
|
252
|
+
}));
|
|
253
|
+
}
|
|
158
254
|
/** Every app in every account this token or session can see. */
|
|
159
255
|
export async function listExpoApps(auth) {
|
|
160
256
|
const { meActor } = await expoGraphQL(auth, `{ meActor { accounts { id name } } }`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eas-client.js","sourceRoot":"","sources":["../../../src/commands/migrate/eas-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,gBAAgB,GAAG,8BAA8B,CAAC;AAiBxD,KAAK,UAAU,WAAW,CACxB,IAAc,EACd,KAAa,EACb,SAAmC;IAEnC,IAAI,GAAa,CAAC;IAClB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,KAAK,CAAC,gBAAgB,EAAE;YAClC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO;oBACvB,CAAC,CAAC,EAAE,aAAa,EAAE,UAAU,IAAI,CAAC,KAAK,EAAE,EAAE;oBAC3C,CAAC,CAAC,EAAE,cAAc,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC;gBAC3C,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;YAC1C,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;SACpC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,
|
|
1
|
+
{"version":3,"file":"eas-client.js","sourceRoot":"","sources":["../../../src/commands/migrate/eas-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { AuthedConfig } from './auth.ts';
|
|
2
|
+
import { type ExpoAuth } from './eas-client.ts';
|
|
3
|
+
import type { ProjectReport } from './report.ts';
|
|
4
|
+
/**
|
|
5
|
+
* Copies the app's EAS environment variables into BuildAtlas's env store.
|
|
6
|
+
*
|
|
7
|
+
* EAS keys a value by environment (production / preview / development), while
|
|
8
|
+
* BuildAtlas keys one value per name, scoped to build profiles. Environment
|
|
9
|
+
* names are carried over as profile names, which is what eas.json's default
|
|
10
|
+
* profiles are called. When a name has different values per environment, only
|
|
11
|
+
* one fits: production's is kept, and the rest are reported so nobody discovers
|
|
12
|
+
* the missing preview value from a broken preview build.
|
|
13
|
+
*
|
|
14
|
+
* Never migrated, always reported:
|
|
15
|
+
* - `SECRET` variables — EAS does not return their values to anyone;
|
|
16
|
+
* - file variables (a `google-services.json` uploaded with `eas env:create
|
|
17
|
+
* --type file`) — the build sets those to a path on EAS's own machine, which
|
|
18
|
+
* has no BuildAtlas equivalent; commit the file or set it up by hand.
|
|
19
|
+
*
|
|
20
|
+
* Add-only, like `buildatlas env pull`: a key already set in BuildAtlas was put
|
|
21
|
+
* there deliberately and is left alone.
|
|
22
|
+
*/
|
|
23
|
+
export declare function migrateEnv(config: AuthedConfig, slug: string, auth: ExpoAuth, appId: string, report: ProjectReport): Promise<void>;
|
|
24
|
+
//# sourceMappingURL=env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../../src/commands/migrate/env.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAkB,KAAK,QAAQ,EAAiB,MAAM,iBAAiB,CAAC;AAC/E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAOjD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,IAAI,CAAC,CAoGf"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { apiRequest } from '../../client.js';
|
|
2
|
+
import { getEasEnvVars } from './eas-client.js';
|
|
3
|
+
import { withRetry } from './retry.js';
|
|
4
|
+
/**
|
|
5
|
+
* Copies the app's EAS environment variables into BuildAtlas's env store.
|
|
6
|
+
*
|
|
7
|
+
* EAS keys a value by environment (production / preview / development), while
|
|
8
|
+
* BuildAtlas keys one value per name, scoped to build profiles. Environment
|
|
9
|
+
* names are carried over as profile names, which is what eas.json's default
|
|
10
|
+
* profiles are called. When a name has different values per environment, only
|
|
11
|
+
* one fits: production's is kept, and the rest are reported so nobody discovers
|
|
12
|
+
* the missing preview value from a broken preview build.
|
|
13
|
+
*
|
|
14
|
+
* Never migrated, always reported:
|
|
15
|
+
* - `SECRET` variables — EAS does not return their values to anyone;
|
|
16
|
+
* - file variables (a `google-services.json` uploaded with `eas env:create
|
|
17
|
+
* --type file`) — the build sets those to a path on EAS's own machine, which
|
|
18
|
+
* has no BuildAtlas equivalent; commit the file or set it up by hand.
|
|
19
|
+
*
|
|
20
|
+
* Add-only, like `buildatlas env pull`: a key already set in BuildAtlas was put
|
|
21
|
+
* there deliberately and is left alone.
|
|
22
|
+
*/
|
|
23
|
+
export async function migrateEnv(config, slug, auth, appId, report) {
|
|
24
|
+
const vars = await withRetry('fetching EAS environment variables', () => getEasEnvVars(auth, appId));
|
|
25
|
+
if (!vars) {
|
|
26
|
+
report.failed('environment variables', 'could not read them from EAS — rerun migrate to try again');
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
if (vars.length === 0) {
|
|
30
|
+
report.skipped('environment variables', 'none on EAS');
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const existing = await withRetry('checking environment variables already set', () => apiRequest(config, `/projects/${slug}/env`, { token: config.token }));
|
|
34
|
+
const existingKeys = new Set((existing?.env ?? []).map((row) => row.key));
|
|
35
|
+
// Every environment this app uses anywhere: a variable present in all of them
|
|
36
|
+
// applies to every profile, which BuildAtlas spells as an empty list.
|
|
37
|
+
const allEnvironments = new Set(vars.flatMap((v) => v.environments));
|
|
38
|
+
const byName = new Map();
|
|
39
|
+
for (const v of vars)
|
|
40
|
+
byName.set(v.name, [...(byName.get(v.name) ?? []), v]);
|
|
41
|
+
for (const [name, entries] of [...byName].sort(([a], [b]) => a.localeCompare(b))) {
|
|
42
|
+
const stepLabel = `env ${name}`;
|
|
43
|
+
if (existingKeys.has(name)) {
|
|
44
|
+
report.skipped(stepLabel, 'already set in BuildAtlas');
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
const file = entries.find((e) => e.type === 'FILE_BASE64');
|
|
48
|
+
if (file) {
|
|
49
|
+
report.warn(stepLabel, `file variable${file.fileName ? ` (${file.fileName})` : ''} — not migrated; commit the file to the repo instead`);
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
const readable = entries.filter((e) => e.value !== null);
|
|
53
|
+
if (readable.length === 0) {
|
|
54
|
+
report.warn(stepLabel, `secret on EAS, value not readable — set it with \`buildatlas credentials set-env ${name} --project ${slug}\``);
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
// Group environments by value; one group fits in BuildAtlas.
|
|
58
|
+
const groups = new Map();
|
|
59
|
+
for (const e of readable) {
|
|
60
|
+
const group = groups.get(e.value) ?? { environments: [], sensitive: false };
|
|
61
|
+
group.environments.push(...e.environments);
|
|
62
|
+
group.sensitive ||= e.visibility !== 'PUBLIC';
|
|
63
|
+
groups.set(e.value, group);
|
|
64
|
+
}
|
|
65
|
+
const [value, kept] = [...groups].sort(([, a], [, b]) => Number(b.environments.includes('production')) - Number(a.environments.includes('production')) ||
|
|
66
|
+
b.environments.length - a.environments.length)[0];
|
|
67
|
+
const coversEverything = groups.size === 1 &&
|
|
68
|
+
entries.length === readable.length &&
|
|
69
|
+
[...allEnvironments].every((env) => kept.environments.includes(env));
|
|
70
|
+
const profiles = coversEverything ? [] : [...new Set(kept.environments)].sort();
|
|
71
|
+
const saved = await withRetry(`setting ${name}`, () => apiRequest(config, `/projects/${slug}/env`, {
|
|
72
|
+
method: 'PUT',
|
|
73
|
+
token: config.token,
|
|
74
|
+
body: JSON.stringify({
|
|
75
|
+
key: name,
|
|
76
|
+
value,
|
|
77
|
+
profiles,
|
|
78
|
+
// PUBLIC stays readable in the dashboard; anything EAS hid stays hidden.
|
|
79
|
+
visibility: kept.sensitive ? 'secret' : 'plaintext',
|
|
80
|
+
}),
|
|
81
|
+
}));
|
|
82
|
+
if (saved === undefined) {
|
|
83
|
+
report.failed(stepLabel, 'not saved');
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
const scope = profiles.length ? `profiles: ${profiles.join(', ')}` : 'all profiles';
|
|
87
|
+
const left = [...groups.values()]
|
|
88
|
+
.filter((g) => g !== kept)
|
|
89
|
+
.flatMap((g) => g.environments)
|
|
90
|
+
.concat(entries.filter((e) => e.value === null).flatMap((e) => e.environments));
|
|
91
|
+
if (left.length) {
|
|
92
|
+
report.warn(stepLabel, `${scope}; differs on EAS for ${[...new Set(left)].join(', ')} — that value was not migrated`);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
report.done(stepLabel, scope);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../../src/commands/migrate/env.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/migrate/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/migrate/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuBzC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAyE7D"}
|
|
@@ -8,14 +8,16 @@ import { requireAuth } from './auth.js';
|
|
|
8
8
|
import { continueBuildNumbers } from './build-numbers.js';
|
|
9
9
|
import { migrateCredentials } from './credentials.js';
|
|
10
10
|
import { getAppIdentifiers, listExpoApps } from './eas-client.js';
|
|
11
|
+
import { migrateEnv } from './env.js';
|
|
11
12
|
import { getExpoSession } from './expo-session.js';
|
|
12
13
|
import { offerToLinkProject } from './link-project.js';
|
|
14
|
+
import { printSummary, ProjectReport } from './report.js';
|
|
13
15
|
export function registerMigrateCommand(program) {
|
|
14
16
|
program
|
|
15
17
|
.command('migrate')
|
|
16
|
-
.description('Pick
|
|
18
|
+
.description('Pick one or more EAS projects and create the matching BuildAtlas projects')
|
|
17
19
|
.option('--expo-token <token>', 'Expo access token. Skips using an `eas login` session.')
|
|
18
|
-
.option('--slug <slug>', 'BuildAtlas slug to use (default: the EAS project slug)')
|
|
20
|
+
.option('--slug <slug>', 'BuildAtlas slug to use (default: the EAS project slug; one project only)')
|
|
19
21
|
.option('--dir <path>', 'Project directory to read app.json / app.config from', process.cwd())
|
|
20
22
|
.action(async (opts) => {
|
|
21
23
|
await run(async () => {
|
|
@@ -39,70 +41,156 @@ export function registerMigrateCommand(program) {
|
|
|
39
41
|
const apps = await withSpinner('fetching EAS projects', () => listExpoApps(auth));
|
|
40
42
|
if (apps.length === 0)
|
|
41
43
|
throw new Error('That account has no EAS projects.');
|
|
42
|
-
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const existing = await apiRequest(config, `/projects/${slug}`, {
|
|
51
|
-
token: config.token,
|
|
52
|
-
}).catch((err) => {
|
|
53
|
-
if (err instanceof AtlasApiError && err.code === 'not_found')
|
|
54
|
-
return undefined;
|
|
55
|
-
throw err;
|
|
56
|
-
});
|
|
57
|
-
// Either way, end up with a project to migrate credentials into. A project
|
|
58
|
-
// that already exists is not a reason to stop — it is the common case for
|
|
59
|
-
// someone re-running `migrate` after rotating a certificate on EAS, and
|
|
60
|
-
// stopping here used to skip credentials entirely.
|
|
61
|
-
let project;
|
|
62
|
-
if (existing) {
|
|
63
|
-
console.log(`${pc.dim('already exists —')} ${pc.bold(existing.project.slug)}`);
|
|
64
|
-
project = existing.project;
|
|
44
|
+
// Only to label the picker; a failure here just means no labels.
|
|
45
|
+
const known = await apiRequest(config, '/projects', { token: config.token })
|
|
46
|
+
.then((r) => r.projects)
|
|
47
|
+
.catch(() => []);
|
|
48
|
+
const detected = detectApp(apps, local);
|
|
49
|
+
const chosen = await pickApps(apps, detected, known);
|
|
50
|
+
if (opts.slug && chosen.length > 1) {
|
|
51
|
+
throw new Error('--slug names one project, but several were selected. Drop --slug or pick one.');
|
|
65
52
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
53
|
+
const reports = [];
|
|
54
|
+
for (const [i, app] of chosen.entries()) {
|
|
55
|
+
console.log(`\n${pc.cyan(`[${i + 1}/${chosen.length}]`)} ${pc.bold(app.fullName)}`);
|
|
56
|
+
const report = new ProjectReport(app.fullName);
|
|
57
|
+
reports.push(report);
|
|
58
|
+
// The local checkout only describes the app it belongs to — its bundle id
|
|
59
|
+
// must never be stamped onto some other project picked in the same run.
|
|
60
|
+
const isLocal = app === detected || (chosen.length === 1 && !detected);
|
|
61
|
+
try {
|
|
62
|
+
await migrateApp({
|
|
63
|
+
config,
|
|
64
|
+
auth,
|
|
65
|
+
app,
|
|
66
|
+
slug: opts.slug ?? app.slug,
|
|
67
|
+
local: isLocal ? local : undefined,
|
|
68
|
+
dir: isLocal ? dir : undefined,
|
|
69
|
+
report,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
// One project failing must not stop the others; the summary says which.
|
|
74
|
+
report.aborted =
|
|
75
|
+
err instanceof AtlasApiError ? `${err.message} (${err.code})` : err.message;
|
|
76
|
+
console.log(` ${pc.red('✖')} ${pc.red(report.aborted)}`);
|
|
77
|
+
}
|
|
79
78
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
console.log(pc.dim(` Bundle id / package name were not both found in ${dir} or on EAS — fill in what's ` +
|
|
84
|
-
`missing with \`buildatlas projects set --project ${project.slug}\`.`));
|
|
85
|
-
}
|
|
86
|
-
await offerToLinkProject(dir, project.slug);
|
|
79
|
+
printSummary(reports);
|
|
80
|
+
if (reports.some((r) => r.status === 'failed'))
|
|
81
|
+
process.exitCode = 1;
|
|
87
82
|
});
|
|
88
83
|
});
|
|
89
84
|
}
|
|
85
|
+
async function migrateApp(params) {
|
|
86
|
+
const { config, auth, app, slug, local, dir, report } = params;
|
|
87
|
+
// Local app.json wins when it disagrees — it's the current source of truth for
|
|
88
|
+
// this checkout — but EAS's own credentials fill in whatever local didn't have,
|
|
89
|
+
// so migrate doesn't need to run from inside a fully-configured project dir.
|
|
90
|
+
const remote = await withSpinner('reading EAS app identifiers', () => getAppIdentifiers(auth, app.id)).catch(() => ({}));
|
|
91
|
+
const bundleIdentifier = local?.bundleIdentifier ?? remote.bundleIdentifier;
|
|
92
|
+
const androidPackage = local?.androidPackage ?? remote.androidPackage;
|
|
93
|
+
const existing = await apiRequest(config, `/projects/${slug}`, {
|
|
94
|
+
token: config.token,
|
|
95
|
+
}).catch((err) => {
|
|
96
|
+
if (err instanceof AtlasApiError && err.code === 'not_found')
|
|
97
|
+
return undefined;
|
|
98
|
+
throw err;
|
|
99
|
+
});
|
|
100
|
+
// Either way, end up with a project to migrate credentials into. A project
|
|
101
|
+
// that already exists is not a reason to stop — it is the common case for
|
|
102
|
+
// someone re-running `migrate` after rotating a certificate on EAS, and
|
|
103
|
+
// stopping here used to skip credentials entirely.
|
|
104
|
+
// Slugs are only unique within an Expo account: `@a/app` and `@b/app` both
|
|
105
|
+
// want "app". Topping up a project that was migrated from a *different* EAS
|
|
106
|
+
// project would sign this app with the other one's certificates.
|
|
107
|
+
if (existing?.project.easProjectId && existing.project.easProjectId !== app.id) {
|
|
108
|
+
throw new Error(`BuildAtlas project "${slug}" was migrated from a different EAS project. ` +
|
|
109
|
+
`Migrate ${app.fullName} on its own with \`--slug <another-slug>\`.`);
|
|
110
|
+
}
|
|
111
|
+
let project;
|
|
112
|
+
if (existing) {
|
|
113
|
+
project = existing.project;
|
|
114
|
+
report.skipped(`project ${project.slug}`, 'already exists');
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
project = (await withSpinner('creating BuildAtlas project', () => apiRequest(config, '/projects', {
|
|
118
|
+
method: 'POST',
|
|
119
|
+
token: config.token,
|
|
120
|
+
body: JSON.stringify({
|
|
121
|
+
slug,
|
|
122
|
+
name: app.name,
|
|
123
|
+
easProjectId: app.id,
|
|
124
|
+
bundleIdentifier,
|
|
125
|
+
androidPackage,
|
|
126
|
+
}),
|
|
127
|
+
}))).project;
|
|
128
|
+
report.done(`project ${project.slug}`, 'created');
|
|
129
|
+
}
|
|
130
|
+
if (existing && project.bundleIdentifier && project.androidPackage) {
|
|
131
|
+
report.skipped('identifiers', `already set: ${project.bundleIdentifier} · ${project.androidPackage}`);
|
|
132
|
+
}
|
|
133
|
+
else if (existing && (bundleIdentifier || androidPackage)) {
|
|
134
|
+
// Found them, but this project was created without them and migrate does not
|
|
135
|
+
// rewrite an existing project's settings.
|
|
136
|
+
report.warn('identifiers', `project is missing some; found ${[bundleIdentifier, androidPackage].filter(Boolean).join(' · ')} — ` +
|
|
137
|
+
`set with \`buildatlas projects set --project ${project.slug}\``);
|
|
138
|
+
}
|
|
139
|
+
else if (bundleIdentifier && androidPackage) {
|
|
140
|
+
report.done('identifiers', `${bundleIdentifier} · ${androidPackage}`);
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
report.warn('identifiers', `${bundleIdentifier ? '' : 'iOS bundle id'}${!bundleIdentifier && !androidPackage ? ' and ' : ''}` +
|
|
144
|
+
`${androidPackage ? '' : 'Android package'} not found locally or on EAS — ` +
|
|
145
|
+
`set with \`buildatlas projects set --project ${project.slug}\``);
|
|
146
|
+
}
|
|
147
|
+
await continueBuildNumbers(config, project.slug, auth, app.id, { bundleIdentifier, androidPackage }, report);
|
|
148
|
+
await migrateCredentials(config, project.slug, auth, app.id, report);
|
|
149
|
+
await migrateEnv(config, project.slug, auth, app.id, report);
|
|
150
|
+
if (dir)
|
|
151
|
+
await offerToLinkProject(dir, project.slug);
|
|
152
|
+
}
|
|
90
153
|
/**
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
154
|
+
* The app this directory already points at — matched by EAS project id first,
|
|
155
|
+
* since a slug is only unique within an account and `app.json` does not say
|
|
156
|
+
* which account it belongs to.
|
|
94
157
|
*/
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
(local?.slug && apps.find((a) => a.slug === local.slug))
|
|
98
|
-
|
|
158
|
+
function detectApp(apps, local) {
|
|
159
|
+
return ((local?.easProjectId && apps.find((a) => a.id === local.easProjectId)) ||
|
|
160
|
+
(local?.slug && apps.find((a) => a.slug === local.slug)) ||
|
|
161
|
+
undefined);
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Checkbox list, with the app this directory belongs to ticked already. Without
|
|
165
|
+
* a terminal to ask in (CI), the detected app is the whole answer, as it was
|
|
166
|
+
* before more than one could be picked.
|
|
167
|
+
*/
|
|
168
|
+
async function pickApps(apps, detected, known) {
|
|
169
|
+
// Picking one of these again is fine — it reruns and tops up whatever is
|
|
170
|
+
// missing — but it should not look like a fresh migration.
|
|
171
|
+
const hintFor = (a) => {
|
|
172
|
+
if (known.some((p) => p.easProjectId === a.id))
|
|
173
|
+
return `${a.name} · already in BuildAtlas`;
|
|
174
|
+
const taken = known.find((p) => p.slug === a.slug);
|
|
175
|
+
// A project made by hand has no EAS id; migrate fills that one in.
|
|
176
|
+
if (taken && !taken.easProjectId)
|
|
177
|
+
return `${a.name} · already in BuildAtlas`;
|
|
178
|
+
if (taken)
|
|
179
|
+
return `${a.name} · slug taken by another app, needs --slug`;
|
|
180
|
+
return a.name;
|
|
181
|
+
};
|
|
182
|
+
if (detected)
|
|
99
183
|
console.log(pc.dim(` detected ${detected.fullName} from app config`));
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
184
|
+
if (detected && !process.stdin.isTTY)
|
|
185
|
+
return [detected];
|
|
186
|
+
if (apps.length === 1)
|
|
187
|
+
return apps;
|
|
188
|
+
const chosen = await withPrompter((p) => p.multiSelect('Which EAS projects?', apps.map((a) => ({
|
|
189
|
+
value: a.fullName,
|
|
190
|
+
label: a.fullName,
|
|
191
|
+
hint: hintFor(a),
|
|
192
|
+
})), { initial: detected ? [detected.fullName] : [] }));
|
|
193
|
+
return apps.filter((a) => chosen.includes(a.fullName));
|
|
106
194
|
}
|
|
107
195
|
async function run(fn) {
|
|
108
196
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/migrate/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/migrate/index.ts"],"names":[],"mappings":"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"}
|