@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
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { AuthedConfig } from './auth.ts';
|
|
2
2
|
import { type ExpoAuth } from './eas-client.ts';
|
|
3
|
+
import type { ProjectReport } from './report.ts';
|
|
3
4
|
/**
|
|
4
5
|
* Points BuildAtlas's build counters past whatever the stores have already
|
|
5
6
|
* accepted from Expo, so the first BuildAtlas build doesn't collide with a
|
|
@@ -8,5 +9,5 @@ import { type ExpoAuth } from './eas-client.ts';
|
|
|
8
9
|
export declare function continueBuildNumbers(config: AuthedConfig, slug: string, auth: ExpoAuth, appId: string, local: {
|
|
9
10
|
bundleIdentifier?: string;
|
|
10
11
|
androidPackage?: string;
|
|
11
|
-
} | undefined): Promise<void>;
|
|
12
|
+
} | undefined, report: ProjectReport): Promise<void>;
|
|
12
13
|
//# sourceMappingURL=build-numbers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-numbers.d.ts","sourceRoot":"","sources":["../../../src/commands/migrate/build-numbers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"build-numbers.d.ts","sourceRoot":"","sources":["../../../src/commands/migrate/build-numbers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,KAAK,QAAQ,EAAyB,MAAM,iBAAiB,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,MAAM,EACb,KAAK,EAAE;IAAE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,EACzE,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,IAAI,CAAC,CAoDf"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import pc from 'picocolors';
|
|
2
1
|
import { apiRequest } from '../../client.js';
|
|
3
2
|
import { getLatestBuildVersion } from './eas-client.js';
|
|
4
3
|
import { withRetry } from './retry.js';
|
|
@@ -7,28 +6,49 @@ import { withRetry } from './retry.js';
|
|
|
7
6
|
* accepted from Expo, so the first BuildAtlas build doesn't collide with a
|
|
8
7
|
* version number Apple/Google have already seen.
|
|
9
8
|
*/
|
|
10
|
-
export async function continueBuildNumbers(config, slug, auth, appId, local) {
|
|
9
|
+
export async function continueBuildNumbers(config, slug, auth, appId, local, report) {
|
|
11
10
|
const platforms = [
|
|
12
11
|
{ platform: 'ios', applicationIdentifier: local?.bundleIdentifier },
|
|
13
12
|
{ platform: 'android', applicationIdentifier: local?.androidPackage },
|
|
14
13
|
];
|
|
14
|
+
// What BuildAtlas will hand out next. Read first because the API only ever
|
|
15
|
+
// raises a counter: on a rerun after BuildAtlas has built past Expo, writing
|
|
16
|
+
// Expo's number would be refused, and that is not a failure — it is done.
|
|
17
|
+
const current = await withRetry('reading BuildAtlas build numbers', () => apiRequest(config, `/projects/${slug}/build-numbers`, {
|
|
18
|
+
token: config.token,
|
|
19
|
+
}));
|
|
15
20
|
for (const { platform, applicationIdentifier } of platforms) {
|
|
16
21
|
if (!applicationIdentifier)
|
|
17
22
|
continue;
|
|
18
|
-
const
|
|
19
|
-
|
|
23
|
+
const stepLabel = `${platform} build number`;
|
|
24
|
+
// Wrapped so "Expo has no build" and "the check failed" stay distinguishable.
|
|
25
|
+
const checked = await withRetry(`checking Expo's ${platform} build number`, async () => ({
|
|
26
|
+
latest: await getLatestBuildVersion(auth, appId, platform, applicationIdentifier),
|
|
27
|
+
}));
|
|
28
|
+
if (!checked) {
|
|
29
|
+
report.failed(stepLabel, "could not read Expo's build number");
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
const { latest } = checked;
|
|
33
|
+
if (latest === undefined) {
|
|
34
|
+
report.skipped(stepLabel, 'no build on Expo yet');
|
|
20
35
|
continue;
|
|
36
|
+
}
|
|
21
37
|
const nextBuildNumber = latest + 1;
|
|
38
|
+
if (current && current[platform] >= nextBuildNumber) {
|
|
39
|
+
report.skipped(stepLabel, `already continues from ${current[platform]} (Expo was at ${latest})`);
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
22
42
|
const synced = await withRetry(`syncing ${platform} build number`, () => apiRequest(config, `/projects/${slug}/build-number`, {
|
|
23
43
|
method: 'PATCH',
|
|
24
44
|
token: config.token,
|
|
25
45
|
body: JSON.stringify({ platform, nextBuildNumber }),
|
|
26
46
|
}));
|
|
27
47
|
if (synced === undefined) {
|
|
28
|
-
|
|
48
|
+
report.failed(stepLabel, `not updated — set it with \`buildatlas projects set-build-number ${nextBuildNumber}\``);
|
|
29
49
|
continue;
|
|
30
50
|
}
|
|
31
|
-
|
|
51
|
+
report.done(stepLabel, `continues from ${nextBuildNumber} (Expo was at ${latest})`);
|
|
32
52
|
}
|
|
33
53
|
}
|
|
34
54
|
//# sourceMappingURL=build-numbers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-numbers.js","sourceRoot":"","sources":["../../../src/commands/migrate/build-numbers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"build-numbers.js","sourceRoot":"","sources":["../../../src/commands/migrate/build-numbers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EAAiB,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAEvE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,MAAoB,EACpB,IAAY,EACZ,IAAc,EACd,KAAa,EACb,KAAyE,EACzE,MAAqB;IAErB,MAAM,SAAS,GAAsE;QACnF,EAAE,QAAQ,EAAE,KAAK,EAAE,qBAAqB,EAAE,KAAK,EAAE,gBAAgB,EAAE;QACnE,EAAE,QAAQ,EAAE,SAAS,EAAE,qBAAqB,EAAE,KAAK,EAAE,cAAc,EAAE;KACtE,CAAC;IAEF,2EAA2E;IAC3E,6EAA6E;IAC7E,0EAA0E;IAC1E,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,kCAAkC,EAAE,GAAG,EAAE,CACvE,UAAU,CAAmC,MAAM,EAAE,aAAa,IAAI,gBAAgB,EAAE;QACtF,KAAK,EAAE,MAAM,CAAC,KAAK;KACpB,CAAC,CACH,CAAC;IAEF,KAAK,MAAM,EAAE,QAAQ,EAAE,qBAAqB,EAAE,IAAI,SAAS,EAAE,CAAC;QAC5D,IAAI,CAAC,qBAAqB;YAAE,SAAS;QACrC,MAAM,SAAS,GAAG,GAAG,QAAQ,eAAe,CAAC;QAE7C,8EAA8E;QAC9E,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,mBAAmB,QAAQ,eAAe,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;YACvF,MAAM,EAAE,MAAM,qBAAqB,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,qBAAqB,CAAC;SAClF,CAAC,CAAC,CAAC;QACJ,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,oCAAoC,CAAC,CAAC;YAC/D,SAAS;QACX,CAAC;QACD,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;QAC3B,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,sBAAsB,CAAC,CAAC;YAClD,SAAS;QACX,CAAC;QAED,MAAM,eAAe,GAAG,MAAM,GAAG,CAAC,CAAC;QACnC,IAAI,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,eAAe,EAAE,CAAC;YACpD,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,0BAA0B,OAAO,CAAC,QAAQ,CAAC,iBAAiB,MAAM,GAAG,CAAC,CAAC;YACjG,SAAS;QACX,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,WAAW,QAAQ,eAAe,EAAE,GAAG,EAAE,CACtE,UAAU,CAAC,MAAM,EAAE,aAAa,IAAI,eAAe,EAAE;YACnD,MAAM,EAAE,OAAO;YACf,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,eAAe,EAAE,CAAC;SACpD,CAAC,CACH,CAAC;QACF,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,oEAAoE,eAAe,IAAI,CAAC,CAAC;YAClH,SAAS;QACX,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,kBAAkB,eAAe,iBAAiB,MAAM,GAAG,CAAC,CAAC;IACtF,CAAC;AACH,CAAC"}
|
|
@@ -1,24 +1,26 @@
|
|
|
1
1
|
import type { AuthedConfig } from './auth.ts';
|
|
2
2
|
import { type ExpoAuth } from './eas-client.ts';
|
|
3
|
+
import type { ProjectReport } from './report.ts';
|
|
3
4
|
/**
|
|
4
|
-
* Pulls
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* Pulls everything EAS holds for this app into BuildAtlas's vault, so a
|
|
6
|
+
* migrated project can build and submit immediately instead of needing someone
|
|
7
|
+
* to run `eas credentials` by hand and re-upload the files themselves:
|
|
8
|
+
*
|
|
9
|
+
* - iOS: distribution cert, and a provisioning profile for *every* target —
|
|
10
|
+
* the app plus extensions such as OneSignal's notification service extension
|
|
11
|
+
* - iOS: APNs push key (what OneSignal and every other sender deliver through)
|
|
12
|
+
* - iOS: App Store Connect API key used for submissions
|
|
13
|
+
* - Android: upload keystore, and the Play service account used for submissions
|
|
9
14
|
*
|
|
10
15
|
* Runs the same way whether the BuildAtlas project was just created or already
|
|
11
16
|
* existed — `migrate` on a project that is already linked is how someone picks
|
|
12
|
-
* up credentials generated on EAS after the fact
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* not pile up duplicate rows for the same kind.
|
|
17
|
+
* up credentials generated on EAS after the fact. What is already in the vault
|
|
18
|
+
* (this project's own row, or a shared one) is left alone rather than
|
|
19
|
+
* re-uploaded, so running this repeatedly does not pile up duplicate rows.
|
|
16
20
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* OneSignal's own dashboard separately; that step has no EAS equivalent to
|
|
21
|
-
* migrate from.
|
|
21
|
+
* Not migrated, and reported as such: the FCM V1 key (only Expo's own push
|
|
22
|
+
* service reads it) and anything OneSignal keeps on its own dashboard, which
|
|
23
|
+
* EAS has no copy of.
|
|
22
24
|
*/
|
|
23
|
-
export declare function migrateCredentials(config: AuthedConfig, slug: string, auth: ExpoAuth, appId: string,
|
|
25
|
+
export declare function migrateCredentials(config: AuthedConfig, slug: string, auth: ExpoAuth, appId: string, report: ProjectReport): Promise<void>;
|
|
24
26
|
//# sourceMappingURL=credentials.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../../src/commands/migrate/credentials.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../../src/commands/migrate/credentials.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,KAAK,QAAQ,EAA8D,MAAM,iBAAiB,CAAC;AAC5G,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAUjD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,IAAI,CAAC,CA4Hf"}
|
|
@@ -1,63 +1,102 @@
|
|
|
1
|
-
import pc from 'picocolors';
|
|
2
1
|
import { apiRequest } from '../../client.js';
|
|
3
|
-
import { getEasCredentials } from './eas-client.js';
|
|
2
|
+
import { getEasCredentials, getEasServiceKeys, mainBundleIdentifier } from './eas-client.js';
|
|
4
3
|
import { withRetry } from './retry.js';
|
|
5
4
|
/**
|
|
6
|
-
* Pulls
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
5
|
+
* Pulls everything EAS holds for this app into BuildAtlas's vault, so a
|
|
6
|
+
* migrated project can build and submit immediately instead of needing someone
|
|
7
|
+
* to run `eas credentials` by hand and re-upload the files themselves:
|
|
8
|
+
*
|
|
9
|
+
* - iOS: distribution cert, and a provisioning profile for *every* target —
|
|
10
|
+
* the app plus extensions such as OneSignal's notification service extension
|
|
11
|
+
* - iOS: APNs push key (what OneSignal and every other sender deliver through)
|
|
12
|
+
* - iOS: App Store Connect API key used for submissions
|
|
13
|
+
* - Android: upload keystore, and the Play service account used for submissions
|
|
11
14
|
*
|
|
12
15
|
* Runs the same way whether the BuildAtlas project was just created or already
|
|
13
16
|
* existed — `migrate` on a project that is already linked is how someone picks
|
|
14
|
-
* up credentials generated on EAS after the fact
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* not pile up duplicate rows for the same kind.
|
|
17
|
+
* up credentials generated on EAS after the fact. What is already in the vault
|
|
18
|
+
* (this project's own row, or a shared one) is left alone rather than
|
|
19
|
+
* re-uploaded, so running this repeatedly does not pile up duplicate rows.
|
|
18
20
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* OneSignal's own dashboard separately; that step has no EAS equivalent to
|
|
23
|
-
* migrate from.
|
|
21
|
+
* Not migrated, and reported as such: the FCM V1 key (only Expo's own push
|
|
22
|
+
* service reads it) and anything OneSignal keeps on its own dashboard, which
|
|
23
|
+
* EAS has no copy of.
|
|
24
24
|
*/
|
|
25
|
-
export async function migrateCredentials(config, slug, auth, appId,
|
|
25
|
+
export async function migrateCredentials(config, slug, auth, appId, report) {
|
|
26
26
|
const creds = await withRetry('fetching signing credentials from EAS', () => getEasCredentials(auth, appId));
|
|
27
|
-
if (!creds
|
|
28
|
-
|
|
29
|
-
'shipped before, generate them with `eas credentials`, then run ' +
|
|
30
|
-
`\`buildatlas credentials add --project ${slug}\`.`));
|
|
27
|
+
if (!creds) {
|
|
28
|
+
report.failed('signing credentials', 'could not read them from EAS — rerun migrate to try again');
|
|
31
29
|
return;
|
|
32
30
|
}
|
|
33
|
-
// Already-vaulted
|
|
34
|
-
//
|
|
35
|
-
//
|
|
36
|
-
// back to attempting every upload, same as before this existed.
|
|
31
|
+
// Already-vaulted rows — this project's own plus whatever it inherits shared —
|
|
32
|
+
// so a rerun tops up what is missing instead of duplicating what a build would
|
|
33
|
+
// already find. A failed check falls back to attempting every upload.
|
|
37
34
|
const existingList = await withRetry('checking what is already stored', () => apiRequest(config, `/projects/${slug}/credentials`, {
|
|
38
35
|
token: config.token,
|
|
39
36
|
}));
|
|
40
|
-
const
|
|
41
|
-
const
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
const result = await withRetry(`uploading ${kind}`, () => apiRequest(config, `/projects/${slug}/credentials`, {
|
|
37
|
+
const existing = (existingList?.credentials ?? []).filter((row) => !row.revokedAt);
|
|
38
|
+
const haveKind = (kind) => existing.some((row) => row.kind === kind);
|
|
39
|
+
const haveProfileFor = (bundleId) => existing.some((row) => row.kind === 'ios_provisioning_profile' && row.meta?.appId === bundleId);
|
|
40
|
+
const label = `migrated from ${report.name}`;
|
|
41
|
+
const upload = async (kind, payload, stepLabel = kind) => {
|
|
42
|
+
const result = await withRetry(`uploading ${stepLabel}`, () => apiRequest(config, `/projects/${slug}/credentials`, {
|
|
48
43
|
method: 'POST',
|
|
49
44
|
token: config.token,
|
|
50
45
|
body: JSON.stringify({ kind, label, payload }),
|
|
51
46
|
}));
|
|
52
|
-
|
|
47
|
+
if (result === undefined)
|
|
48
|
+
report.failed(stepLabel, 'upload failed');
|
|
49
|
+
else
|
|
50
|
+
report.done(stepLabel);
|
|
53
51
|
};
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
52
|
+
// iOS --------------------------------------------------------------------
|
|
53
|
+
if (creds.ios.length === 0) {
|
|
54
|
+
report.skipped('iOS signing', 'none on EAS');
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
const main = mainBundleIdentifier(creds.ios.map((t) => t.bundleIdentifier));
|
|
58
|
+
const mainTarget = creds.ios.find((t) => t.bundleIdentifier === main) ?? creds.ios[0];
|
|
59
|
+
if (haveKind('ios_dist_cert')) {
|
|
60
|
+
report.skipped('ios_dist_cert', 'already in the vault');
|
|
58
61
|
}
|
|
62
|
+
else {
|
|
63
|
+
await upload('ios_dist_cert', { p12Base64: mainTarget.p12Base64, password: mainTarget.password ?? '' });
|
|
64
|
+
}
|
|
65
|
+
// Extensions first, the app itself last: the vault hands out the newest
|
|
66
|
+
// profile when a build can only take one, and that should be the app's.
|
|
67
|
+
const ordered = [...creds.ios.filter((t) => t !== mainTarget), mainTarget];
|
|
68
|
+
for (const target of ordered) {
|
|
69
|
+
const stepLabel = `ios_provisioning_profile (${target.bundleIdentifier})`;
|
|
70
|
+
if (!target.profileBase64) {
|
|
71
|
+
report.warn(stepLabel, 'EAS has no App Store profile for this target — add one with `buildatlas credentials add`');
|
|
72
|
+
}
|
|
73
|
+
else if (haveProfileFor(target.bundleIdentifier)) {
|
|
74
|
+
report.skipped(stepLabel, 'already in the vault');
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
await upload('ios_provisioning_profile', { profileBase64: target.profileBase64 }, stepLabel);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (creds.iosPushKey) {
|
|
82
|
+
if (haveKind('ios_push_key')) {
|
|
83
|
+
report.skipped('ios_push_key', 'already in the vault');
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
await upload('ios_push_key', { keyId: creds.iosPushKey.keyId, p8Base64: creds.iosPushKey.p8Base64 });
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
else if (creds.ios.length) {
|
|
90
|
+
report.warn('ios_push_key', 'none on EAS — if the app sends push (OneSignal included), add the .p8 with `buildatlas credentials add`');
|
|
91
|
+
}
|
|
92
|
+
// Android ----------------------------------------------------------------
|
|
93
|
+
if (!creds.android) {
|
|
94
|
+
report.skipped('android_keystore', 'none on EAS');
|
|
59
95
|
}
|
|
60
|
-
if (
|
|
96
|
+
else if (haveKind('android_keystore')) {
|
|
97
|
+
report.skipped('android_keystore', 'already in the vault');
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
61
100
|
await upload('android_keystore', {
|
|
62
101
|
keystoreBase64: creds.android.keystoreBase64,
|
|
63
102
|
keystorePassword: creds.android.keystorePassword,
|
|
@@ -66,13 +105,39 @@ export async function migrateCredentials(config, slug, auth, appId, appFullName)
|
|
|
66
105
|
keyPassword: creds.android.keyPassword ?? creds.android.keystorePassword,
|
|
67
106
|
});
|
|
68
107
|
}
|
|
69
|
-
|
|
70
|
-
|
|
108
|
+
// Submission and push keys ------------------------------------------------
|
|
109
|
+
const keys = await withRetry('fetching submission and push keys from EAS', () => getEasServiceKeys(auth, appId));
|
|
110
|
+
if (!keys) {
|
|
111
|
+
report.warn('submission keys', 'could not read them from EAS (needs an Admin role on the Expo account)');
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (!keys.ascApiKey) {
|
|
115
|
+
report.skipped('asc_api_key', 'none on EAS');
|
|
116
|
+
}
|
|
117
|
+
else if (!keys.ascApiKey.issuerId) {
|
|
118
|
+
report.warn('asc_api_key', 'EAS has an individual key, which has no issuer id — add a team key with `buildatlas credentials add`');
|
|
119
|
+
}
|
|
120
|
+
else if (haveKind('asc_api_key')) {
|
|
121
|
+
report.skipped('asc_api_key', 'already in the vault');
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
await upload('asc_api_key', {
|
|
125
|
+
keyId: keys.ascApiKey.keyId,
|
|
126
|
+
issuerId: keys.ascApiKey.issuerId,
|
|
127
|
+
p8Base64: keys.ascApiKey.p8Base64,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
if (!keys.playServiceAccountJson) {
|
|
131
|
+
report.skipped('play_service_account', 'none on EAS');
|
|
132
|
+
}
|
|
133
|
+
else if (haveKind('play_service_account')) {
|
|
134
|
+
report.skipped('play_service_account', 'already in the vault');
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
await upload('play_service_account', { serviceAccountJson: keys.playServiceAccountJson });
|
|
71
138
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
'through OneSignal), generate one with `eas credentials` or add it directly: ' +
|
|
75
|
-
`\`buildatlas credentials add\` → iOS push notification key.`));
|
|
139
|
+
if (keys.fcmV1) {
|
|
140
|
+
report.skipped('FCM V1 key', `${keys.fcmV1.clientEmail} stays on EAS — only Expo's push service reads it; builds and OneSignal do not`);
|
|
76
141
|
}
|
|
77
142
|
}
|
|
78
143
|
//# sourceMappingURL=credentials.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../../src/commands/migrate/credentials.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../../src/commands/migrate/credentials.ts"],"names":[],"mappings":"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"}
|
|
@@ -45,7 +45,9 @@ export declare function getAppIdentifiers(auth: ExpoAuth, appId: string): Promis
|
|
|
45
45
|
bundleIdentifier?: string;
|
|
46
46
|
androidPackage?: string;
|
|
47
47
|
}>;
|
|
48
|
-
|
|
48
|
+
/** Signing material for one iOS target — the app itself, or one of its extensions. */
|
|
49
|
+
export interface EasIosTarget {
|
|
50
|
+
bundleIdentifier: string;
|
|
49
51
|
p12Base64: string;
|
|
50
52
|
password?: string;
|
|
51
53
|
profileBase64?: string;
|
|
@@ -61,14 +63,24 @@ export interface EasAndroidCredentials {
|
|
|
61
63
|
keyPassword?: string;
|
|
62
64
|
}
|
|
63
65
|
/**
|
|
64
|
-
* The
|
|
65
|
-
*
|
|
66
|
+
* The main app's bundle id out of a set that may include extensions — the one
|
|
67
|
+
* every other id extends (`com.app` for `com.app.OneSignalNotificationServiceExtension`).
|
|
68
|
+
* Falls back to the first when nothing nests, which is the single-target case.
|
|
69
|
+
*/
|
|
70
|
+
export declare function mainBundleIdentifier(ids: string[]): string | undefined;
|
|
71
|
+
/**
|
|
72
|
+
* The actual signing material EAS holds for this app — a distribution cert and
|
|
73
|
+
* provisioning profile per iOS target, a keystore for Android, and an APNs
|
|
66
74
|
* push key if one was ever generated for push notifications — in the same
|
|
67
75
|
* base64 shape `buildatlas credentials add` already expects (`ios_dist_cert`,
|
|
68
76
|
* `ios_provisioning_profile`, `android_keystore`, `ios_push_key`), so it can be
|
|
69
77
|
* forwarded as-is.
|
|
70
78
|
*
|
|
71
|
-
*
|
|
79
|
+
* Every iOS target, not just the first: an app with a notification service
|
|
80
|
+
* extension (OneSignal's, for one) has its own bundle id and its own profile on
|
|
81
|
+
* EAS, and an archive with a target missing its profile fails to export.
|
|
82
|
+
*
|
|
83
|
+
* Picks the App Store build credentials per target (ad-hoc/enterprise/development
|
|
72
84
|
* profiles are for internal testing, not what a migrated app should ship with)
|
|
73
85
|
* and whichever Android keystore is marked default. Omits a platform, or the
|
|
74
86
|
* push key, entirely rather than guessing when EAS has never generated one.
|
|
@@ -79,10 +91,50 @@ export interface EasAndroidCredentials {
|
|
|
79
91
|
* worker to warn about when a project looks push-capable but has none stored.
|
|
80
92
|
*/
|
|
81
93
|
export declare function getEasCredentials(auth: ExpoAuth, appId: string): Promise<{
|
|
82
|
-
ios
|
|
94
|
+
ios: EasIosTarget[];
|
|
83
95
|
android?: EasAndroidCredentials;
|
|
84
96
|
iosPushKey?: EasIosPushKey;
|
|
85
97
|
}>;
|
|
98
|
+
export interface EasServiceKeys {
|
|
99
|
+
/** App Store Connect API key EAS Submit uses. Null issuer = an individual key, which BuildAtlas cannot use. */
|
|
100
|
+
ascApiKey?: {
|
|
101
|
+
keyId: string;
|
|
102
|
+
issuerId: string | null;
|
|
103
|
+
p8Base64: string;
|
|
104
|
+
};
|
|
105
|
+
/** Google service account EAS Submit uses for Play uploads. */
|
|
106
|
+
playServiceAccountJson?: string;
|
|
107
|
+
/**
|
|
108
|
+
* Firebase Cloud Messaging V1 service account, which only Expo's own push
|
|
109
|
+
* service reads. Reported, not stored: nothing in a build uses it, and
|
|
110
|
+
* OneSignal or a self-run sender keep their own copy.
|
|
111
|
+
*/
|
|
112
|
+
fcmV1?: {
|
|
113
|
+
projectId: string;
|
|
114
|
+
clientEmail: string;
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* The keys EAS keeps for submitting and push, separate from the signing query
|
|
119
|
+
* above: reading raw key material needs a higher role on the Expo account, and
|
|
120
|
+
* a permission error here should not cost the signing credentials too.
|
|
121
|
+
*/
|
|
122
|
+
export declare function getEasServiceKeys(auth: ExpoAuth, appId: string): Promise<EasServiceKeys>;
|
|
123
|
+
export interface EasEnvVar {
|
|
124
|
+
name: string;
|
|
125
|
+
/** Null for `SECRET` visibility — EAS never hands those back, to anyone. */
|
|
126
|
+
value: string | null;
|
|
127
|
+
environments: string[];
|
|
128
|
+
visibility: 'PUBLIC' | 'SENSITIVE' | 'SECRET';
|
|
129
|
+
type: 'STRING' | 'FILE_BASE64';
|
|
130
|
+
fileName: string | null;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* The app's EAS environment variables across every environment, with
|
|
134
|
+
* `SENSITIVE` values included (what `eas env:pull` reads). One variable may
|
|
135
|
+
* appear several times with different values — one record per environment.
|
|
136
|
+
*/
|
|
137
|
+
export declare function getEasEnvVars(auth: ExpoAuth, appId: string): Promise<EasEnvVar[]>;
|
|
86
138
|
/** Every app in every account this token or session can see. */
|
|
87
139
|
export declare function listExpoApps(auth: ExpoAuth): Promise<ExpoApp[]>;
|
|
88
140
|
//# sourceMappingURL=eas-client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eas-client.d.ts","sourceRoot":"","sources":["../../../src/commands/migrate/eas-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,sFAAsF;IACtF,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"eas-client.d.ts","sourceRoot":"","sources":["../../../src/commands/migrate/eas-client.ts"],"names":[],"mappings":"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"}
|