@better-update/cli 0.15.3 → 0.16.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/dist/index.mjs +285 -57
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -2
package/dist/index.mjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import { spawn, spawnSync } from "node:child_process";
|
|
4
4
|
import { defineCommand, runMain } from "citty";
|
|
5
|
-
import { Console, Context, Data, Deferred, Duration, Effect,
|
|
5
|
+
import { Console, Context, Data, Deferred, Duration, Effect, Layer, Match, Option, ParseResult, Schema } from "effect";
|
|
6
6
|
import { Command, FetchHttpClient, FileSystem, HttpApi, HttpApiClient, HttpApiEndpoint, HttpApiGroup, HttpApiMiddleware, HttpApiSchema, HttpApiSecurity, HttpClient, HttpClientRequest, OpenApi, Path } from "@effect/platform";
|
|
7
7
|
import { NodeContext } from "@effect/platform-node";
|
|
8
8
|
import path, { join } from "node:path";
|
|
@@ -15,6 +15,8 @@ import { maxBy, uniqBy } from "es-toolkit";
|
|
|
15
15
|
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
16
16
|
import forge from "node-forge";
|
|
17
17
|
import { createReadStream, existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
18
|
+
import { spawn as spawn$1 } from "node-pty";
|
|
19
|
+
import chalk from "chalk";
|
|
18
20
|
import os from "node:os";
|
|
19
21
|
import plistMod from "@expo/plist";
|
|
20
22
|
import { ExpoRunFormatter } from "@expo/xcpretty";
|
|
@@ -28,7 +30,7 @@ var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
|
28
30
|
|
|
29
31
|
//#endregion
|
|
30
32
|
//#region package.json
|
|
31
|
-
var version = "0.
|
|
33
|
+
var version = "0.16.0";
|
|
32
34
|
|
|
33
35
|
//#endregion
|
|
34
36
|
//#region src/lib/interactive-mode.ts
|
|
@@ -4388,56 +4390,178 @@ const sha256Namespaced = (contentType, contentSha256Hex) => {
|
|
|
4388
4390
|
return toBase64Url(createHash("sha256").update(input).digest());
|
|
4389
4391
|
};
|
|
4390
4392
|
|
|
4393
|
+
//#endregion
|
|
4394
|
+
//#region src/lib/pty-runner.ts
|
|
4395
|
+
const ptyDimensions = () => {
|
|
4396
|
+
const stdout = process$1.stdout;
|
|
4397
|
+
return {
|
|
4398
|
+
cols: typeof stdout.columns === "number" && stdout.columns > 0 ? stdout.columns : 120,
|
|
4399
|
+
rows: typeof stdout.rows === "number" && stdout.rows > 0 ? stdout.rows : 40
|
|
4400
|
+
};
|
|
4401
|
+
};
|
|
4402
|
+
const mergeEnv$1 = (overrides) => {
|
|
4403
|
+
const merged = {};
|
|
4404
|
+
for (const [key, value] of Object.entries(process$1.env)) if (typeof value === "string") merged[key] = value;
|
|
4405
|
+
for (const [key, value] of Object.entries(overrides)) merged[key] = value;
|
|
4406
|
+
return merged;
|
|
4407
|
+
};
|
|
4408
|
+
const trySpawn = (input) => {
|
|
4409
|
+
const { cols, rows } = ptyDimensions();
|
|
4410
|
+
try {
|
|
4411
|
+
return spawn$1(input.command, [...input.args], {
|
|
4412
|
+
name: "xterm-256color",
|
|
4413
|
+
cols,
|
|
4414
|
+
rows,
|
|
4415
|
+
cwd: input.cwd,
|
|
4416
|
+
env: mergeEnv$1(input.env)
|
|
4417
|
+
});
|
|
4418
|
+
} catch (error) {
|
|
4419
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
4420
|
+
}
|
|
4421
|
+
};
|
|
4422
|
+
/**
|
|
4423
|
+
* Run a command in a pseudo-terminal so the subprocess sees a real TTY
|
|
4424
|
+
* (preserves spinners, progress bars, and ANSI colors emitted by tools like
|
|
4425
|
+
* CocoaPods and `expo prebuild`). Subprocess output is tee'd: forwarded to
|
|
4426
|
+
* `process.stdout` as raw bytes (so colors/positioning are preserved), and
|
|
4427
|
+
* also buffered into lines for the optional `onLine` callback.
|
|
4428
|
+
*
|
|
4429
|
+
* Returns the subprocess exit code. Spawn failures and signal exits surface
|
|
4430
|
+
* as non-zero exit codes (128+signal for Unix-style signal exits).
|
|
4431
|
+
*/
|
|
4432
|
+
const runInPty = (input) => Effect.async((resume) => {
|
|
4433
|
+
const spawned = trySpawn(input);
|
|
4434
|
+
if (spawned instanceof Error) {
|
|
4435
|
+
process$1.stderr.write(`Failed to spawn "${input.command}" in pty: ${spawned.message}\n`);
|
|
4436
|
+
resume(Effect.succeed(1));
|
|
4437
|
+
return;
|
|
4438
|
+
}
|
|
4439
|
+
const proc = spawned;
|
|
4440
|
+
let lineBuf = "";
|
|
4441
|
+
const handleLine = (line) => {
|
|
4442
|
+
if (input.onLine === void 0) return;
|
|
4443
|
+
const annotation = input.onLine(line);
|
|
4444
|
+
if (annotation !== void 0) process$1.stdout.write(`${annotation}\n`);
|
|
4445
|
+
};
|
|
4446
|
+
proc.onData((chunk) => {
|
|
4447
|
+
if (input.silent !== true) process$1.stdout.write(chunk);
|
|
4448
|
+
if (input.onLine === void 0) return;
|
|
4449
|
+
lineBuf += chunk;
|
|
4450
|
+
let nl = lineBuf.indexOf("\n");
|
|
4451
|
+
while (nl !== -1) {
|
|
4452
|
+
const line = lineBuf.slice(0, nl).replace(/\r$/u, "");
|
|
4453
|
+
lineBuf = lineBuf.slice(nl + 1);
|
|
4454
|
+
handleLine(line);
|
|
4455
|
+
nl = lineBuf.indexOf("\n");
|
|
4456
|
+
}
|
|
4457
|
+
});
|
|
4458
|
+
const handleResize = () => {
|
|
4459
|
+
const { cols, rows } = ptyDimensions();
|
|
4460
|
+
try {
|
|
4461
|
+
proc.resize(cols, rows);
|
|
4462
|
+
} catch {}
|
|
4463
|
+
};
|
|
4464
|
+
process$1.stdout.on("resize", handleResize);
|
|
4465
|
+
proc.onExit(({ exitCode, signal }) => {
|
|
4466
|
+
process$1.stdout.off("resize", handleResize);
|
|
4467
|
+
if (lineBuf.length > 0) {
|
|
4468
|
+
handleLine(lineBuf.replace(/\r$/u, ""));
|
|
4469
|
+
lineBuf = "";
|
|
4470
|
+
}
|
|
4471
|
+
const code = signal !== void 0 && signal !== 0 ? 128 + signal : exitCode;
|
|
4472
|
+
resume(Effect.succeed(code));
|
|
4473
|
+
});
|
|
4474
|
+
return Effect.sync(() => {
|
|
4475
|
+
try {
|
|
4476
|
+
proc.kill();
|
|
4477
|
+
} catch {}
|
|
4478
|
+
process$1.stdout.off("resize", handleResize);
|
|
4479
|
+
});
|
|
4480
|
+
});
|
|
4481
|
+
|
|
4482
|
+
//#endregion
|
|
4483
|
+
//#region src/lib/warning-style.ts
|
|
4484
|
+
const ANSI_REGEX_GLOBAL = /[][[()#;?]*(?:\d{1,4}(?:;\d{0,4})*)?[\dA-ORZcf-ntqry=><]/gu;
|
|
4485
|
+
const stripAnsi = (input) => input.replaceAll(ANSI_REGEX_GLOBAL, "");
|
|
4486
|
+
const hasAnsi = (input) => {
|
|
4487
|
+
ANSI_REGEX_GLOBAL.lastIndex = 0;
|
|
4488
|
+
return ANSI_REGEX_GLOBAL.test(input);
|
|
4489
|
+
};
|
|
4490
|
+
const WARNING_PATTERNS = [
|
|
4491
|
+
/^\s*warning:/iu,
|
|
4492
|
+
/^\s*\[!\]/u,
|
|
4493
|
+
/^\s*WARNING:/u,
|
|
4494
|
+
/^\s*WARN\b/u,
|
|
4495
|
+
/\bis deprecated\b/iu,
|
|
4496
|
+
/^\s*DEPRECATION\b/iu,
|
|
4497
|
+
/\[MT\]/u,
|
|
4498
|
+
/⚠/u
|
|
4499
|
+
];
|
|
4500
|
+
const isWarningLine = (rawLine) => {
|
|
4501
|
+
const plain = stripAnsi(rawLine);
|
|
4502
|
+
return WARNING_PATTERNS.some((pattern) => pattern.test(plain));
|
|
4503
|
+
};
|
|
4504
|
+
/**
|
|
4505
|
+
* Style a single output line as a warning. If the line already contains ANSI
|
|
4506
|
+
* escapes (the subprocess pre-colored it), only prepend our yellow ⚠ marker
|
|
4507
|
+
* so the original colors survive. Otherwise color the whole line yellow.
|
|
4508
|
+
*/
|
|
4509
|
+
const styleWarningLine = (line) => hasAnsi(line) ? `${chalk.yellow("⚠")} ${line}` : chalk.yellow(`⚠ ${line}`);
|
|
4510
|
+
/**
|
|
4511
|
+
* Emit a CLI-owned warning. Suppressed in JSON mode; in human mode writes a
|
|
4512
|
+
* yellow, ⚠-prefixed line to stderr so it stands out from regular info logs.
|
|
4513
|
+
*/
|
|
4514
|
+
const printWarn = (message) => Effect.gen(function* () {
|
|
4515
|
+
if ((yield* OutputMode).json) return;
|
|
4516
|
+
yield* Console.warn(chalk.yellow(`⚠ warning: ${message}`));
|
|
4517
|
+
});
|
|
4518
|
+
|
|
4391
4519
|
//#endregion
|
|
4392
4520
|
//#region src/commands/build/run-step.ts
|
|
4393
|
-
const
|
|
4521
|
+
const buildFailed = (step, exitCode, message) => new BuildFailedError({
|
|
4394
4522
|
step,
|
|
4395
|
-
exitCode
|
|
4396
|
-
message
|
|
4397
|
-
})
|
|
4398
|
-
|
|
4399
|
-
|
|
4400
|
-
|
|
4401
|
-
|
|
4523
|
+
exitCode,
|
|
4524
|
+
message
|
|
4525
|
+
});
|
|
4526
|
+
const annotateWarning = (line) => isWarningLine(line) ? styleWarningLine(line) : void 0;
|
|
4527
|
+
/**
|
|
4528
|
+
* Run a build step in a PTY so the subprocess sees a real TTY (spinners,
|
|
4529
|
+
* progress bars, ANSI colors are preserved). Completed lines are inspected
|
|
4530
|
+
* and any detected warning is re-echoed with our yellow ⚠ annotation.
|
|
4531
|
+
*/
|
|
4532
|
+
const runStep = (cmd, step) => runInPty({
|
|
4533
|
+
command: cmd.command,
|
|
4534
|
+
args: cmd.args,
|
|
4535
|
+
cwd: cmd.cwd,
|
|
4536
|
+
env: cmd.env,
|
|
4537
|
+
onLine: annotateWarning
|
|
4538
|
+
}).pipe(Effect.flatMap((code) => code === 0 ? Effect.void : Effect.fail(buildFailed(step, code, `${step} exited with code ${code}`))));
|
|
4402
4539
|
/**
|
|
4403
|
-
* Run a build step
|
|
4404
|
-
*
|
|
4540
|
+
* Run a build step in a PTY, but feed each completed line through the supplied
|
|
4541
|
+
* xcpretty-style formatter before writing. Warning detection still applies to
|
|
4542
|
+
* the formatter's output so xcodebuild deprecation notices stand out.
|
|
4543
|
+
*
|
|
4544
|
+
* The PTY guarantees xcodebuild sees a real TTY (so it keeps colored output);
|
|
4545
|
+
* the formatter strips noise. On failure the formatter's build summary is
|
|
4546
|
+
* flushed to stderr to help diagnose.
|
|
4405
4547
|
*/
|
|
4406
4548
|
const runStepFormatted = (cmd, step, formatter) => Effect.gen(function* () {
|
|
4407
|
-
const
|
|
4408
|
-
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
for (const output of formatted) process$1.stdout.write(`${output}\n`);
|
|
4416
|
-
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
exitCode: 1,
|
|
4420
|
-
message: `${step} stdout stream error: ${String(cause)}`
|
|
4421
|
-
})), Effect.fork);
|
|
4422
|
-
const stderrFiber = yield* proc.stderr.pipe(Stream.decodeText(), Stream.splitLines, Stream.runForEach((line) => Effect.sync(() => process$1.stderr.write(`${line}\n`))), Effect.mapError((cause) => new BuildFailedError({
|
|
4423
|
-
step,
|
|
4424
|
-
exitCode: 1,
|
|
4425
|
-
message: `${step} stderr stream error: ${String(cause)}`
|
|
4426
|
-
})), Effect.fork);
|
|
4427
|
-
yield* Effect.all([Fiber.join(stdoutFiber), Fiber.join(stderrFiber)], { concurrency: 2 }).pipe(Effect.catchAll(() => Effect.void));
|
|
4428
|
-
const code = yield* proc.exitCode.pipe(Effect.mapError((cause) => new BuildFailedError({
|
|
4429
|
-
step,
|
|
4430
|
-
exitCode: 1,
|
|
4431
|
-
message: `${step} exit code error: ${String(cause)}`
|
|
4432
|
-
})));
|
|
4549
|
+
const code = yield* runInPty({
|
|
4550
|
+
command: cmd.command,
|
|
4551
|
+
args: cmd.args,
|
|
4552
|
+
cwd: cmd.cwd,
|
|
4553
|
+
env: cmd.env,
|
|
4554
|
+
silent: true,
|
|
4555
|
+
onLine: (line) => {
|
|
4556
|
+
const formatted = formatter.pipe(line);
|
|
4557
|
+
for (const output of formatted) if (isWarningLine(output)) process$1.stdout.write(`${styleWarningLine(output)}\n`);
|
|
4558
|
+
else process$1.stdout.write(`${output}\n`);
|
|
4559
|
+
}
|
|
4560
|
+
});
|
|
4433
4561
|
if (code !== 0) {
|
|
4434
4562
|
const summary = formatter.getBuildSummary();
|
|
4435
|
-
if (summary) process$1.stderr.write(`${summary}\n`);
|
|
4436
|
-
return yield*
|
|
4437
|
-
step,
|
|
4438
|
-
exitCode: code,
|
|
4439
|
-
message: `${step} exited with code ${code}`
|
|
4440
|
-
});
|
|
4563
|
+
if (summary.length > 0) process$1.stderr.write(`${summary}\n`);
|
|
4564
|
+
return yield* Effect.fail(buildFailed(step, code, `${step} exited with code ${code}`));
|
|
4441
4565
|
}
|
|
4442
4566
|
});
|
|
4443
4567
|
|
|
@@ -4470,7 +4594,18 @@ const runAndroidBuild = (input) => Effect.gen(function* () {
|
|
|
4470
4594
|
applicationIdentifier,
|
|
4471
4595
|
tempDir
|
|
4472
4596
|
});
|
|
4473
|
-
yield* runStep(
|
|
4597
|
+
yield* runStep({
|
|
4598
|
+
command: "bunx",
|
|
4599
|
+
args: [
|
|
4600
|
+
"expo",
|
|
4601
|
+
"prebuild",
|
|
4602
|
+
"--platform",
|
|
4603
|
+
"android",
|
|
4604
|
+
"--clean"
|
|
4605
|
+
],
|
|
4606
|
+
cwd: projectRoot,
|
|
4607
|
+
env: commandEnv
|
|
4608
|
+
}, "expo prebuild android");
|
|
4474
4609
|
const fs = yield* FileSystem.FileSystem;
|
|
4475
4610
|
const signingGradlePath = path.join(tempDir, "signing.gradle");
|
|
4476
4611
|
yield* fs.writeFileString(signingGradlePath, renderSigningGradle({
|
|
@@ -4479,8 +4614,16 @@ const runAndroidBuild = (input) => Effect.gen(function* () {
|
|
|
4479
4614
|
keyAlias: credentials.keyAlias,
|
|
4480
4615
|
keyPassword: credentials.keyPassword
|
|
4481
4616
|
}));
|
|
4482
|
-
|
|
4483
|
-
|
|
4617
|
+
yield* runStep({
|
|
4618
|
+
command: "./gradlew",
|
|
4619
|
+
args: [
|
|
4620
|
+
"--init-script",
|
|
4621
|
+
signingGradlePath,
|
|
4622
|
+
`:app:${gradleTaskName(format, flavor, buildType)}`
|
|
4623
|
+
],
|
|
4624
|
+
cwd: androidDir,
|
|
4625
|
+
env: commandEnv
|
|
4626
|
+
}, "gradlew");
|
|
4484
4627
|
const artifactPath = yield* findAndroidArtifact({
|
|
4485
4628
|
projectRoot,
|
|
4486
4629
|
format,
|
|
@@ -5127,6 +5270,12 @@ const applyTargetSigning = (options) => Effect.gen(function* () {
|
|
|
5127
5270
|
|
|
5128
5271
|
//#endregion
|
|
5129
5272
|
//#region src/lib/ios-export-options.ts
|
|
5273
|
+
const XCODE_METHOD = {
|
|
5274
|
+
"app-store": "app-store-connect",
|
|
5275
|
+
"ad-hoc": "release-testing",
|
|
5276
|
+
development: "debugging",
|
|
5277
|
+
enterprise: "enterprise"
|
|
5278
|
+
};
|
|
5130
5279
|
const escapeXml = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll("\"", """).replaceAll("'", "'");
|
|
5131
5280
|
const boolTag = (value) => value ? "<true/>" : "<false/>";
|
|
5132
5281
|
/**
|
|
@@ -5145,7 +5294,7 @@ const renderExportOptionsPlist = ({ method, teamId, provisioningProfiles, compil
|
|
|
5145
5294
|
"<plist version=\"1.0\">",
|
|
5146
5295
|
"<dict>",
|
|
5147
5296
|
" <key>method</key>",
|
|
5148
|
-
`\t<string>${escapeXml(method)}</string>`,
|
|
5297
|
+
`\t<string>${escapeXml(XCODE_METHOD[method])}</string>`,
|
|
5149
5298
|
" <key>teamID</key>",
|
|
5150
5299
|
`\t<string>${escapeXml(teamId)}</string>`,
|
|
5151
5300
|
" <key>signingStyle</key>",
|
|
@@ -5327,8 +5476,8 @@ const validateIosBuild = (params) => Effect.gen(function* () {
|
|
|
5327
5476
|
const validatedBundleIds = new Set(perBundle.map((entry) => entry.bundleId).filter((id) => id !== void 0));
|
|
5328
5477
|
for (const expected of params.expectedTargets) if (!validatedBundleIds.has(expected.bundleId)) warnings.push(`Expected signed target "${expected.bundleId}" was not found in the archive.`);
|
|
5329
5478
|
if (warnings.length > 0) {
|
|
5330
|
-
yield*
|
|
5331
|
-
for (const warning of warnings) yield*
|
|
5479
|
+
yield* printWarn("Post-build validation warnings:");
|
|
5480
|
+
for (const warning of warnings) yield* printWarn(` - ${warning}`);
|
|
5332
5481
|
}
|
|
5333
5482
|
return {
|
|
5334
5483
|
passed: warnings.length === 0,
|
|
@@ -5485,8 +5634,24 @@ const findXcworkspace = (iosDir) => Effect.gen(function* () {
|
|
|
5485
5634
|
return workspace;
|
|
5486
5635
|
});
|
|
5487
5636
|
const prebuildAndPods = (params) => Effect.gen(function* () {
|
|
5488
|
-
yield* runStep(
|
|
5489
|
-
|
|
5637
|
+
yield* runStep({
|
|
5638
|
+
command: "bunx",
|
|
5639
|
+
args: [
|
|
5640
|
+
"expo",
|
|
5641
|
+
"prebuild",
|
|
5642
|
+
"--platform",
|
|
5643
|
+
"ios",
|
|
5644
|
+
"--clean"
|
|
5645
|
+
],
|
|
5646
|
+
cwd: params.projectRoot,
|
|
5647
|
+
env: params.commandEnv
|
|
5648
|
+
}, "expo prebuild ios");
|
|
5649
|
+
yield* runStep({
|
|
5650
|
+
command: "pod",
|
|
5651
|
+
args: ["install"],
|
|
5652
|
+
cwd: params.iosDir,
|
|
5653
|
+
env: params.commandEnv
|
|
5654
|
+
}, "pod install");
|
|
5490
5655
|
});
|
|
5491
5656
|
const findAppDirectory = (root) => Effect.gen(function* () {
|
|
5492
5657
|
const fs = yield* FileSystem.FileSystem;
|
|
@@ -5521,13 +5686,46 @@ const runIosSimulatorBuild = (input) => Effect.gen(function* () {
|
|
|
5521
5686
|
const scheme = iosProfile.scheme ?? workspaceFilename.replace(/\.xcworkspace$/u, "");
|
|
5522
5687
|
const configuration = iosProfile.buildConfiguration ?? "Release";
|
|
5523
5688
|
const derivedDataPath = path.join(tempDir, "derived-data");
|
|
5524
|
-
const buildCmd =
|
|
5689
|
+
const buildCmd = {
|
|
5690
|
+
command: "xcodebuild",
|
|
5691
|
+
args: [
|
|
5692
|
+
"-workspace",
|
|
5693
|
+
workspaceFilename,
|
|
5694
|
+
"-scheme",
|
|
5695
|
+
scheme,
|
|
5696
|
+
"-configuration",
|
|
5697
|
+
configuration,
|
|
5698
|
+
"-sdk",
|
|
5699
|
+
"iphonesimulator",
|
|
5700
|
+
"-destination",
|
|
5701
|
+
"generic/platform=iOS Simulator",
|
|
5702
|
+
"-derivedDataPath",
|
|
5703
|
+
derivedDataPath,
|
|
5704
|
+
"build",
|
|
5705
|
+
"CODE_SIGNING_ALLOWED=NO",
|
|
5706
|
+
"CODE_SIGNING_REQUIRED=NO",
|
|
5707
|
+
"CODE_SIGN_IDENTITY="
|
|
5708
|
+
],
|
|
5709
|
+
cwd: iosDir,
|
|
5710
|
+
env: commandEnv
|
|
5711
|
+
};
|
|
5525
5712
|
const formatter = input.rawOutput ? void 0 : createXcodebuildFormatter(projectRoot);
|
|
5526
5713
|
yield* formatter ? runStepFormatted(buildCmd, "xcodebuild build (simulator)", formatter) : runStep(buildCmd, "xcodebuild build (simulator)");
|
|
5527
5714
|
const appDir = yield* findAppDirectory(path.join(derivedDataPath, "Build", "Products", `${configuration}-iphonesimulator`));
|
|
5528
5715
|
const archiveName = `${path.basename(appDir, ".app")}-simulator.tar.gz`;
|
|
5529
5716
|
const archivePath = path.join(tempDir, archiveName);
|
|
5530
|
-
yield* runStep(
|
|
5717
|
+
yield* runStep({
|
|
5718
|
+
command: "tar",
|
|
5719
|
+
args: [
|
|
5720
|
+
"-czf",
|
|
5721
|
+
archivePath,
|
|
5722
|
+
"-C",
|
|
5723
|
+
path.dirname(appDir),
|
|
5724
|
+
path.basename(appDir)
|
|
5725
|
+
],
|
|
5726
|
+
cwd: projectRoot,
|
|
5727
|
+
env: commandEnv
|
|
5728
|
+
}, "tar simulator .app");
|
|
5531
5729
|
const { sha256, byteSize } = yield* sha256File(archivePath);
|
|
5532
5730
|
return {
|
|
5533
5731
|
artifactPath: archivePath,
|
|
@@ -5630,7 +5828,23 @@ const runIosDeviceBuild = (input) => Effect.gen(function* () {
|
|
|
5630
5828
|
}))
|
|
5631
5829
|
});
|
|
5632
5830
|
const archivePath = path.join(tempDir, "build.xcarchive");
|
|
5633
|
-
const archiveCmd =
|
|
5831
|
+
const archiveCmd = {
|
|
5832
|
+
command: "xcodebuild",
|
|
5833
|
+
args: [
|
|
5834
|
+
"-workspace",
|
|
5835
|
+
workspaceFilename,
|
|
5836
|
+
"-scheme",
|
|
5837
|
+
scheme,
|
|
5838
|
+
"-configuration",
|
|
5839
|
+
configuration,
|
|
5840
|
+
"-archivePath",
|
|
5841
|
+
archivePath,
|
|
5842
|
+
"-allowProvisioningUpdates",
|
|
5843
|
+
"archive"
|
|
5844
|
+
],
|
|
5845
|
+
cwd: iosDir,
|
|
5846
|
+
env: commandEnv
|
|
5847
|
+
};
|
|
5634
5848
|
const formatter = input.rawOutput ? void 0 : createXcodebuildFormatter(projectRoot);
|
|
5635
5849
|
yield* formatter ? runStepFormatted(archiveCmd, "xcodebuild archive", formatter) : runStep(archiveCmd, "xcodebuild archive");
|
|
5636
5850
|
const exportOptionsPath = path.join(tempDir, "ExportOptions.plist");
|
|
@@ -5650,7 +5864,21 @@ const runIosDeviceBuild = (input) => Effect.gen(function* () {
|
|
|
5650
5864
|
}))
|
|
5651
5865
|
}));
|
|
5652
5866
|
const exportPath = path.join(tempDir, "export");
|
|
5653
|
-
const exportCmd =
|
|
5867
|
+
const exportCmd = {
|
|
5868
|
+
command: "xcodebuild",
|
|
5869
|
+
args: [
|
|
5870
|
+
"-exportArchive",
|
|
5871
|
+
"-archivePath",
|
|
5872
|
+
archivePath,
|
|
5873
|
+
"-exportPath",
|
|
5874
|
+
exportPath,
|
|
5875
|
+
"-exportOptionsPlist",
|
|
5876
|
+
exportOptionsPath,
|
|
5877
|
+
"-allowProvisioningUpdates"
|
|
5878
|
+
],
|
|
5879
|
+
cwd: iosDir,
|
|
5880
|
+
env: commandEnv
|
|
5881
|
+
};
|
|
5654
5882
|
yield* formatter ? runStepFormatted(exportCmd, "xcodebuild exportArchive", formatter) : runStep(exportCmd, "xcodebuild exportArchive");
|
|
5655
5883
|
yield* validateIosBuild({
|
|
5656
5884
|
archivePath,
|
|
@@ -6235,7 +6463,7 @@ const readGradleConfig = (androidDir) => Effect.gen(function* () {
|
|
|
6235
6463
|
const warnOnGradleMismatch = (gradleConfig, expectedPackage) => {
|
|
6236
6464
|
if (!gradleConfig?.applicationId) return Effect.void;
|
|
6237
6465
|
if (gradleConfig.applicationId === expectedPackage) return Effect.void;
|
|
6238
|
-
return
|
|
6466
|
+
return printWarn(`Gradle applicationId "${gradleConfig.applicationId}" differs from app.json package "${expectedPackage}". The Gradle value will be used in the built APK/AAB.`);
|
|
6239
6467
|
};
|
|
6240
6468
|
/**
|
|
6241
6469
|
* Strip Groovy single-line and block comments.
|