@ship-et/buildatlas-cli 0.0.0-stage → 0.12.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.
Files changed (115) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +81 -2
  3. package/dist/browser-login.d.ts +12 -0
  4. package/dist/browser-login.d.ts.map +1 -0
  5. package/dist/browser-login.js +94 -0
  6. package/dist/browser-login.js.map +1 -0
  7. package/dist/client.d.ts +33 -0
  8. package/dist/client.d.ts.map +1 -0
  9. package/dist/client.js +164 -0
  10. package/dist/client.js.map +1 -0
  11. package/dist/client.test.d.ts +2 -0
  12. package/dist/client.test.d.ts.map +1 -0
  13. package/dist/client.test.js +158 -0
  14. package/dist/client.test.js.map +1 -0
  15. package/dist/commands/auth.d.ts +3 -0
  16. package/dist/commands/auth.d.ts.map +1 -0
  17. package/dist/commands/auth.js +88 -0
  18. package/dist/commands/auth.js.map +1 -0
  19. package/dist/commands/build.d.ts +4 -0
  20. package/dist/commands/build.d.ts.map +1 -0
  21. package/dist/commands/build.js +362 -0
  22. package/dist/commands/build.js.map +1 -0
  23. package/dist/commands/builds.d.ts +3 -0
  24. package/dist/commands/builds.d.ts.map +1 -0
  25. package/dist/commands/builds.js +102 -0
  26. package/dist/commands/builds.js.map +1 -0
  27. package/dist/commands/credentials-wizard.d.ts +25 -0
  28. package/dist/commands/credentials-wizard.d.ts.map +1 -0
  29. package/dist/commands/credentials-wizard.js +274 -0
  30. package/dist/commands/credentials-wizard.js.map +1 -0
  31. package/dist/commands/credentials.d.ts +3 -0
  32. package/dist/commands/credentials.d.ts.map +1 -0
  33. package/dist/commands/credentials.js +249 -0
  34. package/dist/commands/credentials.js.map +1 -0
  35. package/dist/commands/env.d.ts +37 -0
  36. package/dist/commands/env.d.ts.map +1 -0
  37. package/dist/commands/env.js +220 -0
  38. package/dist/commands/env.js.map +1 -0
  39. package/dist/commands/expo-tokens.d.ts +3 -0
  40. package/dist/commands/expo-tokens.d.ts.map +1 -0
  41. package/dist/commands/expo-tokens.js +103 -0
  42. package/dist/commands/expo-tokens.js.map +1 -0
  43. package/dist/commands/init.d.ts +6 -0
  44. package/dist/commands/init.d.ts.map +1 -0
  45. package/dist/commands/init.js +204 -0
  46. package/dist/commands/init.js.map +1 -0
  47. package/dist/commands/projects.d.ts +11 -0
  48. package/dist/commands/projects.d.ts.map +1 -0
  49. package/dist/commands/projects.js +148 -0
  50. package/dist/commands/projects.js.map +1 -0
  51. package/dist/commands/submit.d.ts +10 -0
  52. package/dist/commands/submit.d.ts.map +1 -0
  53. package/dist/commands/submit.js +118 -0
  54. package/dist/commands/submit.js.map +1 -0
  55. package/dist/commands/update.d.ts +10 -0
  56. package/dist/commands/update.d.ts.map +1 -0
  57. package/dist/commands/update.js +93 -0
  58. package/dist/commands/update.js.map +1 -0
  59. package/dist/config.d.ts +66 -0
  60. package/dist/config.d.ts.map +1 -0
  61. package/dist/config.js +255 -0
  62. package/dist/config.js.map +1 -0
  63. package/dist/detach.d.ts +18 -0
  64. package/dist/detach.d.ts.map +1 -0
  65. package/dist/detach.js +42 -0
  66. package/dist/detach.js.map +1 -0
  67. package/dist/eas-credentials-zip.d.ts +38 -0
  68. package/dist/eas-credentials-zip.d.ts.map +1 -0
  69. package/dist/eas-credentials-zip.js +63 -0
  70. package/dist/eas-credentials-zip.js.map +1 -0
  71. package/dist/eas-json.d.ts +21 -0
  72. package/dist/eas-json.d.ts.map +1 -0
  73. package/dist/eas-json.js +32 -0
  74. package/dist/eas-json.js.map +1 -0
  75. package/dist/index.d.ts +3 -0
  76. package/dist/index.d.ts.map +1 -0
  77. package/dist/index.js +67 -0
  78. package/dist/index.js.map +1 -0
  79. package/dist/logs.d.ts +13 -0
  80. package/dist/logs.d.ts.map +1 -0
  81. package/dist/logs.js +70 -0
  82. package/dist/logs.js.map +1 -0
  83. package/dist/packaging.test.d.ts +2 -0
  84. package/dist/packaging.test.d.ts.map +1 -0
  85. package/dist/packaging.test.js +79 -0
  86. package/dist/packaging.test.js.map +1 -0
  87. package/dist/profiles.test.d.ts +2 -0
  88. package/dist/profiles.test.d.ts.map +1 -0
  89. package/dist/profiles.test.js +56 -0
  90. package/dist/profiles.test.js.map +1 -0
  91. package/dist/project-hint.d.ts +12 -0
  92. package/dist/project-hint.d.ts.map +1 -0
  93. package/dist/project-hint.js +19 -0
  94. package/dist/project-hint.js.map +1 -0
  95. package/dist/project-type.d.ts +43 -0
  96. package/dist/project-type.d.ts.map +1 -0
  97. package/dist/project-type.js +88 -0
  98. package/dist/project-type.js.map +1 -0
  99. package/dist/project-type.test.d.ts +2 -0
  100. package/dist/project-type.test.d.ts.map +1 -0
  101. package/dist/project-type.test.js +77 -0
  102. package/dist/project-type.test.js.map +1 -0
  103. package/dist/prompt.d.ts +56 -0
  104. package/dist/prompt.d.ts.map +1 -0
  105. package/dist/prompt.js +157 -0
  106. package/dist/prompt.js.map +1 -0
  107. package/dist/tarball.d.ts +39 -0
  108. package/dist/tarball.d.ts.map +1 -0
  109. package/dist/tarball.js +208 -0
  110. package/dist/tarball.js.map +1 -0
  111. package/dist/tarball.test.d.ts +2 -0
  112. package/dist/tarball.test.d.ts.map +1 -0
  113. package/dist/tarball.test.js +97 -0
  114. package/dist/tarball.test.js.map +1 -0
  115. package/package.json +55 -4
@@ -0,0 +1,274 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { access, readFile } from 'node:fs/promises';
3
+ import { basename, isAbsolute, resolve } from 'node:path';
4
+ import { promisify } from 'node:util';
5
+ import pc from 'picocolors';
6
+ import { looksLikeZip, readEasCertificateZip } from '../eas-credentials-zip.js';
7
+ const exec = promisify(execFile);
8
+ /**
9
+ * Interactive `credentials add`.
10
+ *
11
+ * Running the command bare used to fail with "required option '-k, --kind' not
12
+ * specified", which tells you a flag is missing but not which of six values it
13
+ * takes, nor which extra flags each one then needs. The flags still work and are
14
+ * still what CI uses; this is for the person doing it once by hand.
15
+ *
16
+ * For Android it also offers to *create* the keystore. That is the part most worth
17
+ * automating: keytool's defaults are wrong for this job in three separate ways —
18
+ * it writes to ~/.keystore rather than the project, issues a 90-day certificate
19
+ * that is useless for Play, and names the key `mykey`. Getting any of those wrong
20
+ * is only discovered later.
21
+ */
22
+ export async function runCredentialsWizard(p, defaults) {
23
+ const kind = await p.select('What are you adding?', [
24
+ {
25
+ value: 'android_keystore',
26
+ label: 'Android keystore',
27
+ hint: 'signs every Android build',
28
+ },
29
+ {
30
+ value: 'ios_dist_cert',
31
+ label: 'iOS distribution certificate',
32
+ hint: '.p12, for device and App Store builds',
33
+ },
34
+ {
35
+ value: 'ios_provisioning_profile',
36
+ label: 'iOS provisioning profile',
37
+ hint: '.mobileprovision',
38
+ },
39
+ {
40
+ value: 'asc_api_key',
41
+ label: 'App Store Connect API key',
42
+ hint: '.p8, for store submission',
43
+ },
44
+ {
45
+ value: 'play_service_account',
46
+ label: 'Google Play service account',
47
+ hint: '.json, for store submission',
48
+ },
49
+ ]);
50
+ switch (kind) {
51
+ case 'android_keystore':
52
+ return androidKeystore(p, defaults.dir);
53
+ case 'ios_dist_cert':
54
+ return iosDistCert(p, defaults.dir);
55
+ case 'ios_provisioning_profile':
56
+ return iosProfile(p, defaults.dir);
57
+ case 'asc_api_key':
58
+ return ascApiKey(p, defaults.dir);
59
+ case 'play_service_account':
60
+ return playServiceAccount(p, defaults.dir);
61
+ }
62
+ }
63
+ /** Asks for a path until it points at something readable. */
64
+ async function askForFile(p, question, dir, suggestion) {
65
+ for (let attempt = 0; attempt < 5; attempt++) {
66
+ const answer = await p.ask(question, suggestion ? { default: suggestion } : {});
67
+ if (!answer) {
68
+ console.log(pc.red(' A file is required.'));
69
+ continue;
70
+ }
71
+ // Relative to the project directory, which is where people keep these and
72
+ // therefore what they type.
73
+ const path = isAbsolute(answer) ? answer : resolve(dir, answer.replace(/^~/, homeDir()));
74
+ try {
75
+ await access(path);
76
+ return path;
77
+ }
78
+ catch {
79
+ console.log(pc.red(` Not found: ${path}`));
80
+ }
81
+ }
82
+ throw new Error('Could not find that file.');
83
+ }
84
+ function homeDir() {
85
+ return process.env.HOME ?? '';
86
+ }
87
+ async function base64(path) {
88
+ return (await readFile(path)).toString('base64');
89
+ }
90
+ async function androidKeystore(p, dir) {
91
+ const have = await p.select('Do you have a keystore already?', [
92
+ { value: 'generate', label: 'No — create one now', hint: 'recommended' },
93
+ { value: 'existing', label: 'Yes — I have a .jks or .keystore file' },
94
+ ]);
95
+ let path;
96
+ let alias;
97
+ let password;
98
+ let keyPassword;
99
+ if (have === 'generate') {
100
+ path = resolve(dir, await p.ask('Save the keystore as', { default: 'upload.jks' }));
101
+ alias = await p.ask('Key alias', { default: 'upload' });
102
+ password = await askNewPassword(p);
103
+ const dname = await askDname(p);
104
+ await generateKeystore({ path, alias, password, dname });
105
+ console.log(`${pc.green('✔')} created ${pc.bold(basename(path))} ${pc.dim('(valid 10000 days)')}`);
106
+ console.log(pc.yellow('!'), 'Back this file and its password up somewhere durable now.', '\n Lose them and the app can never be updated on Play — only republished under a new package name.');
107
+ }
108
+ else {
109
+ path = await askForFile(p, 'Path to the keystore', dir, 'upload.jks');
110
+ alias = await p.ask('Key alias', { default: await guessAlias(path) });
111
+ password = await p.askHidden('Keystore password');
112
+ // Only asked for an existing keystore, and only because old JKS files really
113
+ // do have two different passwords. One we generate never does: keytool has
114
+ // defaulted to PKCS12 since JDK 9, which has no separate key password and
115
+ // silently ignores a different one.
116
+ keyPassword = (await p.askHidden('Key password (blank if same as above)')) || undefined;
117
+ }
118
+ const label = await p.ask('Label', { default: `${basename(path)} (${alias})` });
119
+ return {
120
+ kind: 'android_keystore',
121
+ label,
122
+ payload: {
123
+ keystoreBase64: await base64(path),
124
+ keystorePassword: password,
125
+ keyAlias: alias,
126
+ keyPassword: keyPassword ?? password,
127
+ },
128
+ };
129
+ }
130
+ /**
131
+ * Reads the alias out of the keystore so it does not have to be typed.
132
+ *
133
+ * Needs the store password, which we have not asked for yet, so this only works
134
+ * for keystores that list without one. Falls back to the conventional name.
135
+ */
136
+ async function guessAlias(path) {
137
+ try {
138
+ const { stdout } = await exec('keytool', ['-list', '-keystore', path, '-storepass', '']);
139
+ const match = stdout.match(/^(\S+),.*PrivateKeyEntry/m);
140
+ if (match?.[1])
141
+ return match[1];
142
+ }
143
+ catch {
144
+ // Password-protected, which is normal. The default below is the convention.
145
+ }
146
+ return 'upload';
147
+ }
148
+ async function askNewPassword(p) {
149
+ for (let attempt = 0; attempt < 5; attempt++) {
150
+ const first = await p.askHidden('Keystore password (min 6 characters)');
151
+ if (first.length < 6) {
152
+ console.log(pc.red(' keytool requires at least 6 characters.'));
153
+ continue;
154
+ }
155
+ const second = await p.askHidden('Confirm password');
156
+ if (first !== second) {
157
+ console.log(pc.red(' Passwords do not match.'));
158
+ continue;
159
+ }
160
+ return first;
161
+ }
162
+ throw new Error('Could not read a password.');
163
+ }
164
+ async function askDname(p) {
165
+ console.log(pc.dim('\nThese go into the certificate. They are not verified by anyone — use your real'));
166
+ console.log(pc.dim('organisation so the certificate is identifiable later.'));
167
+ const cn = await p.ask('Name (CN)', { default: 'Mobile' });
168
+ const org = await p.ask('Organisation (O)');
169
+ const city = await p.ask('City (L)');
170
+ const country = await p.ask('Two-letter country code (C)', { default: 'ET' });
171
+ const parts = [`CN=${cn}`, org && `O=${org}`, city && `L=${city}`, `C=${country}`].filter(Boolean);
172
+ return parts.join(', ');
173
+ }
174
+ async function generateKeystore(opts) {
175
+ try {
176
+ await exec('keytool', ['-help']);
177
+ }
178
+ catch {
179
+ throw new Error('keytool not found. It ships with the JDK — install one (`brew install --cask temurin`) and try again.');
180
+ }
181
+ try {
182
+ await exec('keytool', [
183
+ '-genkeypair',
184
+ '-storetype',
185
+ 'PKCS12',
186
+ '-keystore',
187
+ opts.path,
188
+ '-alias',
189
+ opts.alias,
190
+ '-keyalg',
191
+ 'RSA',
192
+ '-keysize',
193
+ '2048',
194
+ // ~27 years. keytool's default is 90 days, which Google Play rejects and
195
+ // which would strand even internal builds.
196
+ '-validity',
197
+ '10000',
198
+ '-storepass',
199
+ opts.password,
200
+ // Same as the store password on purpose: see keyPassword above.
201
+ '-keypass',
202
+ opts.password,
203
+ '-dname',
204
+ opts.dname,
205
+ ]);
206
+ }
207
+ catch (err) {
208
+ const message = err.stderr?.trim();
209
+ throw new Error(`keytool failed: ${message || err.message}`);
210
+ }
211
+ }
212
+ async function iosDistCert(p, dir) {
213
+ console.log(pc.dim('\nEither a .p12 exported from Keychain Access (My Certificates → right-click the' +
214
+ '\nprivate key → Export), or the zip that `eas credentials` downloads — that one' +
215
+ '\nalso carries its own password, which will be read for you.'));
216
+ const path = await askForFile(p, 'Path to the .p12 or DistCert_*.zip', dir, 'dist.p12');
217
+ if (looksLikeZip(path)) {
218
+ const bundle = await readEasCertificateZip(path);
219
+ if (!bundle) {
220
+ throw new Error(`${path} is a zip but holds no .p12 — point at the certificate itself.`);
221
+ }
222
+ console.log(`${pc.green('✔')} found ${bundle.p12Name} in the archive`);
223
+ // Asked for only when the archive does not carry it, which an EAS download does.
224
+ const zipPassword = bundle.password ?? (await p.askHidden('.p12 password'));
225
+ if (bundle.password)
226
+ console.log(pc.dim(' password read from the archive'));
227
+ const zipLabel = await p.ask('Label', { default: basename(path, '.zip') });
228
+ return {
229
+ kind: 'ios_dist_cert',
230
+ label: zipLabel,
231
+ payload: { p12Base64: bundle.p12.toString('base64'), password: zipPassword },
232
+ };
233
+ }
234
+ const password = await p.askHidden('Password you set when exporting it');
235
+ const label = await p.ask('Label', { default: 'Distribution certificate' });
236
+ return {
237
+ kind: 'ios_dist_cert',
238
+ label,
239
+ payload: { p12Base64: await base64(path), password },
240
+ };
241
+ }
242
+ async function iosProfile(p, dir) {
243
+ console.log(pc.dim('\nDownload this from developer.apple.com → Certificates, IDs & Profiles → Profiles.'));
244
+ const path = await askForFile(p, 'Path to the .mobileprovision', dir);
245
+ const label = await p.ask('Label', { default: basename(path) });
246
+ return {
247
+ kind: 'ios_provisioning_profile',
248
+ label,
249
+ payload: { profileBase64: await base64(path) },
250
+ };
251
+ }
252
+ async function ascApiKey(p, dir) {
253
+ console.log(pc.dim('\nFrom App Store Connect → Users and Access → Integrations → App Store Connect API.'));
254
+ const path = await askForFile(p, 'Path to the .p8 key file', dir);
255
+ const keyId = await p.ask('Key ID');
256
+ const issuerId = await p.ask('Issuer ID');
257
+ const label = await p.ask('Label', { default: `ASC key ${keyId}` });
258
+ return {
259
+ kind: 'asc_api_key',
260
+ label,
261
+ payload: { p8Base64: await base64(path), keyId, issuerId },
262
+ };
263
+ }
264
+ async function playServiceAccount(p, dir) {
265
+ console.log(pc.dim('\nFrom Google Cloud console → IAM → Service Accounts → Keys → Add key (JSON).'));
266
+ const path = await askForFile(p, 'Path to the service account .json', dir);
267
+ const label = await p.ask('Label', { default: basename(path) });
268
+ return {
269
+ kind: 'play_service_account',
270
+ label,
271
+ payload: { serviceAccountJson: await readFile(path, 'utf8') },
272
+ };
273
+ }
274
+ //# sourceMappingURL=credentials-wizard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials-wizard.js","sourceRoot":"","sources":["../../src/commands/credentials-wizard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ export declare function registerCredentialCommands(program: Command): void;
3
+ //# sourceMappingURL=credentials.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/commands/credentials.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgIzC,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkMjE"}
@@ -0,0 +1,249 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { looksLikeZip, readEasCertificateZip } from '../eas-credentials-zip.js';
3
+ import pc from 'picocolors';
4
+ import { AtlasApiError, apiRequest } from '../client.js';
5
+ import { reportProject } from '../project-hint.js';
6
+ import { runCredentialsWizard } from './credentials-wizard.js';
7
+ import { loadConfig, resolveProject } from '../config.js';
8
+ import { withPrompter } from '../prompt.js';
9
+ const b64 = async (path) => (await readFile(path)).toString('base64');
10
+ async function requireAuth() {
11
+ const config = await loadConfig();
12
+ if (!config.token)
13
+ throw new Error('Not logged in. Run `buildatlas login` first.');
14
+ return config;
15
+ }
16
+ function fail(err) {
17
+ const message = err instanceof AtlasApiError ? `${err.message} (${err.code})` : err.message;
18
+ console.error(pc.red('✖'), message);
19
+ process.exitCode = 1;
20
+ }
21
+ /**
22
+ * Builds the payload for each credential kind.
23
+ *
24
+ * Passwords are prompted for rather than taken as flags, so they never land in
25
+ * shell history. File contents are base64-encoded client-side; the API encrypts
26
+ * them into the vault and no endpoint ever returns them again.
27
+ */
28
+ async function buildPayload(kind, opts, ask) {
29
+ switch (kind) {
30
+ case 'ios_dist_cert': {
31
+ if (!opts.file)
32
+ throw new Error('--file <dist.p12 or DistCert_*.zip> is required');
33
+ // `eas credentials` downloads a zip holding the .p12 and its generated
34
+ // password. Reading both beats asking someone to transcribe 24 characters,
35
+ // which fails as a keychain error mid-build rather than as "wrong password".
36
+ if (looksLikeZip(opts.file)) {
37
+ const bundle = await readEasCertificateZip(opts.file);
38
+ if (bundle) {
39
+ console.log(pc.dim(` found ${bundle.p12Name} in the archive`));
40
+ const password = bundle.password ?? (await ask('.p12 password: '));
41
+ if (bundle.password)
42
+ console.log(pc.dim(' using the password from the archive'));
43
+ return { p12Base64: bundle.p12.toString('base64'), password };
44
+ }
45
+ throw new Error(`${opts.file} is a zip but holds no .p12. Point --file at the certificate itself.`);
46
+ }
47
+ return { p12Base64: await b64(opts.file), password: await ask('.p12 password: ') };
48
+ }
49
+ case 'ios_provisioning_profile': {
50
+ if (!opts.file)
51
+ throw new Error('--file <profile.mobileprovision> is required');
52
+ return { profileBase64: await b64(opts.file) };
53
+ }
54
+ case 'android_keystore': {
55
+ if (!opts.file)
56
+ throw new Error('--file <release.jks> is required for android_keystore');
57
+ const keyAlias = opts.alias ?? (await ask('key alias: '));
58
+ const keystorePassword = await ask('keystore password: ');
59
+ const keyPassword = (await ask('key password (blank = same as keystore): ')) || keystorePassword;
60
+ return { keystoreBase64: await b64(opts.file), keystorePassword, keyAlias, keyPassword };
61
+ }
62
+ case 'asc_api_key': {
63
+ if (!opts.file)
64
+ throw new Error('--file <AuthKey_XXX.p8> is required for asc_api_key');
65
+ return {
66
+ p8Base64: await b64(opts.file),
67
+ keyId: opts.keyId ?? (await ask('App Store Connect key id: ')),
68
+ issuerId: opts.issuerId ?? (await ask('issuer id: ')),
69
+ };
70
+ }
71
+ case 'play_service_account': {
72
+ if (!opts.file)
73
+ throw new Error('--file <service-account.json> is required');
74
+ return { serviceAccountJson: await readFile(opts.file, 'utf8') };
75
+ }
76
+ case 'expo_token':
77
+ throw new Error('Expo tokens moved to `buildatlas expo-tokens add` — they are usually shared by every project, which a per-project credential cannot express.');
78
+ default:
79
+ throw new Error(`Unknown credential kind "${kind}"`);
80
+ }
81
+ }
82
+ /**
83
+ * Renders a credential list. Shared rows are labelled, because "which certificate
84
+ * will sign this" is the question the list exists to answer.
85
+ */
86
+ function printCredentials(rows) {
87
+ if (!rows.length) {
88
+ console.log(pc.dim('No credentials stored.'));
89
+ return;
90
+ }
91
+ for (const row of rows) {
92
+ const expiry = row.expired
93
+ ? pc.red('EXPIRED')
94
+ : row.expiresInDays === null
95
+ ? pc.dim('no expiry')
96
+ : row.expiresInDays < 30
97
+ ? pc.yellow(`expires in ${row.expiresInDays}d`)
98
+ : pc.dim(`expires in ${row.expiresInDays}d`);
99
+ const state = row.revokedAt ? pc.dim(' [revoked]') : '';
100
+ const scope = row.projectId === null ? pc.cyan(' [shared]') : '';
101
+ console.log(`${row.kind.padEnd(26)} ${row.label.padEnd(24)} ${expiry}${state}${scope}`);
102
+ if (row.meta && Object.keys(row.meta).length) {
103
+ console.log(pc.dim(` ${JSON.stringify(row.meta)}`));
104
+ }
105
+ }
106
+ }
107
+ export function registerCredentialCommands(program) {
108
+ const credentials = program
109
+ .command('credentials')
110
+ .description('Manage signing credentials stored in the BuildAtlas vault');
111
+ credentials
112
+ .command('list')
113
+ .description('List stored credentials (metadata only — values are never returned)')
114
+ .option('--project <slug>', 'Project slug (default: $BUILDATLAS_PROJECT, else app.json)')
115
+ .option('--account', 'Only the credentials shared by every project')
116
+ .action(async (opts) => {
117
+ try {
118
+ const config = await requireAuth();
119
+ if (opts.account) {
120
+ const { credentials: rows } = await apiRequest(config, '/credentials', { token: config.token });
121
+ printCredentials(rows);
122
+ return;
123
+ }
124
+ const resolved = await resolveProject(opts.project);
125
+ reportProject(resolved);
126
+ const slug = resolved.slug;
127
+ const { credentials: rows } = await apiRequest(config, `/projects/${slug}/credentials`, { token: config.token });
128
+ printCredentials(rows);
129
+ }
130
+ catch (err) {
131
+ fail(err);
132
+ }
133
+ });
134
+ credentials
135
+ .command('add')
136
+ .description('Upload a credential into the vault')
137
+ // Not required: omitting it starts the interactive wizard. The flags remain
138
+ // the path CI uses, where prompting would hang.
139
+ .option('-k, --kind <kind>', 'ios_dist_cert | ios_provisioning_profile | android_keystore | asc_api_key | play_service_account. Omit to be asked.')
140
+ .option('-f, --file <path>', 'Path to the credential file')
141
+ .option('-l, --label <label>', 'Human-readable label')
142
+ .option('--alias <alias>', 'Keystore key alias')
143
+ .option('--key-id <id>', 'App Store Connect key id')
144
+ .option('--issuer-id <id>', 'App Store Connect issuer id')
145
+ .option('--project <slug>', 'Project slug (default: $BUILDATLAS_PROJECT, else app.json)')
146
+ .option('--account', 'Share with every project. Only for a distribution certificate, ASC key or Play service account.')
147
+ .action(async (opts) => {
148
+ try {
149
+ const config = await requireAuth();
150
+ // An account-level credential belongs to no project, so do not resolve
151
+ // one — inferring a slug we then ignore would only be confusing.
152
+ const slug = opts.account ? undefined : await (async () => {
153
+ const resolved = await resolveProject(opts.project);
154
+ reportProject(resolved);
155
+ return resolved.slug;
156
+ })();
157
+ // Confirm the project exists before doing any work. Otherwise the wizard
158
+ // generates a keystore, asks for passwords twice, prints "created", and only
159
+ // then fails with "Project not found" — leaving a real signing key on disk
160
+ // that was never stored anywhere.
161
+ if (slug) {
162
+ await apiRequest(config, `/projects/${slug}`, { token: config.token });
163
+ }
164
+ const entry = await withPrompter(async (prompter) => {
165
+ if (!opts.kind) {
166
+ return runCredentialsWizard(prompter, { dir: process.cwd() });
167
+ }
168
+ return {
169
+ kind: opts.kind,
170
+ label: opts.label ?? opts.kind,
171
+ payload: await buildPayload(opts.kind, opts, (q) => prompter.ask(q)),
172
+ };
173
+ });
174
+ const { credential } = await apiRequest(config, slug ? `/projects/${slug}/credentials` : '/credentials', {
175
+ method: 'POST',
176
+ token: config.token,
177
+ body: JSON.stringify({
178
+ kind: entry.kind,
179
+ label: opts.label ?? entry.label,
180
+ payload: entry.payload,
181
+ }),
182
+ });
183
+ console.log(pc.green('✔'), `stored ${credential.kind} (${credential.id.slice(0, 8)})${slug ? '' : pc.cyan(' · shared by every project')}`);
184
+ if (credential.expiresAt) {
185
+ console.log(pc.dim(` expires ${new Date(credential.expiresAt).toDateString()}`));
186
+ }
187
+ if (credential.meta && Object.keys(credential.meta).length) {
188
+ console.log(pc.dim(` ${JSON.stringify(credential.meta)}`));
189
+ }
190
+ }
191
+ catch (err) {
192
+ fail(err);
193
+ }
194
+ });
195
+ credentials
196
+ .command('revoke <credentialId>')
197
+ .description('Revoke a credential (kept for audit, no longer used by builds)')
198
+ .option('--project <slug>', 'Project slug (default: $BUILDATLAS_PROJECT, else app.json)')
199
+ .action(async (credentialId, opts) => {
200
+ try {
201
+ const config = await requireAuth();
202
+ const resolved = await resolveProject(opts.project);
203
+ reportProject(resolved);
204
+ const slug = resolved.slug;
205
+ await apiRequest(config, `/projects/${slug}/credentials/${credentialId}`, {
206
+ method: 'DELETE',
207
+ token: config.token,
208
+ });
209
+ console.log(pc.green('✔'), 'revoked');
210
+ }
211
+ catch (err) {
212
+ fail(err);
213
+ }
214
+ });
215
+ credentials
216
+ .command('set-env <key>')
217
+ .description('Store an encrypted environment variable for builds')
218
+ .option('--value <value>', 'Value (avoid: prefer the prompt so it stays out of shell history)')
219
+ // Repeatable, because one value usually belongs to several profiles and the
220
+ // server models it as a list. Omit for "every profile".
221
+ .option('--profile <profile>', 'Build profile this applies to; repeat for several (default: all profiles)', (value, previous = []) => [...previous, value])
222
+ .option('--plaintext', 'Store readable, for values that are not secret (e.g. an API base URL)')
223
+ .option('--project <slug>', 'Project slug (default: $BUILDATLAS_PROJECT, else app.json)')
224
+ .action(async (key, opts) => {
225
+ try {
226
+ const config = await requireAuth();
227
+ const resolved = await resolveProject(opts.project);
228
+ reportProject(resolved);
229
+ const slug = resolved.slug;
230
+ const value = opts.value ?? (await withPrompter((prompter) => prompter.ask(`value for ${key}: `)));
231
+ const profiles = opts.profile ?? [];
232
+ await apiRequest(config, `/projects/${slug}/env`, {
233
+ method: 'PUT',
234
+ token: config.token,
235
+ body: JSON.stringify({
236
+ key,
237
+ value,
238
+ profiles,
239
+ visibility: opts.plaintext ? 'plaintext' : 'secret',
240
+ }),
241
+ });
242
+ console.log(pc.green('✔'), `${key} stored for ${profiles.length ? profiles.join(', ') : 'all profiles'}`);
243
+ }
244
+ catch (err) {
245
+ fail(err);
246
+ }
247
+ });
248
+ }
249
+ //# sourceMappingURL=credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/commands/credentials.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import type { Command } from 'commander';
2
+ import { type AtlasConfig } from '../config.ts';
3
+ /**
4
+ * Copies a profile's `eas.json` env block into the project's BuildAtlas env
5
+ * store. Add-only by default: a value someone already set (or edited) in the
6
+ * dashboard is never silently replaced by whatever a committed eas.json says.
7
+ *
8
+ * Non-fatal by design at the call sites that treat this as a side effect (e.g.
9
+ * `buildatlas build --local`) — the build's own env still comes correctly from
10
+ * the worker merging eas.json directly (see the worker's `inject_env` phase),
11
+ * so a failure here (e.g. a non-admin token, since setting env requires admin)
12
+ * should never block a build.
13
+ */
14
+ export declare function seedEnvFromEasJson(params: {
15
+ config: Pick<AtlasConfig, 'apiUrl' | 'token'>;
16
+ slug: string;
17
+ projectDir: string;
18
+ profile: string;
19
+ overwrite: boolean;
20
+ }): Promise<{
21
+ added: string[];
22
+ skipped: string[];
23
+ }>;
24
+ /**
25
+ * Parses a `.env` file.
26
+ *
27
+ * Deliberately small: `KEY=value`, `#` comments, blank lines, and quotes stripped
28
+ * from a fully quoted value. No interpolation, no `export` prefixes, no multiline —
29
+ * a file that needs those is doing something this importer should not silently
30
+ * half-understand.
31
+ *
32
+ * Values are taken verbatim otherwise, including `=` inside them, because URLs and
33
+ * base64 both contain it.
34
+ */
35
+ export declare function parseDotEnv(text: string): Record<string, string>;
36
+ export declare function registerEnvCommand(program: Command): void;
37
+ //# sourceMappingURL=env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/commands/env.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGzC,OAAO,EAAE,KAAK,WAAW,EAA8B,MAAM,cAAc,CAAC;AAQ5E;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE;IAC/C,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,QAAQ,GAAG,OAAO,CAAC,CAAC;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;CACpB,GAAG,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAiClD;AAGD;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAsBhE;AAyDD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAqGzD"}