@better-update/cli 0.47.5 → 0.48.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 +230 -15
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -35,7 +35,7 @@ var __require = /* #__PURE__ */ (() => createRequire(import.meta.url))();
|
|
|
35
35
|
|
|
36
36
|
//#endregion
|
|
37
37
|
//#region package.json
|
|
38
|
-
var version = "0.
|
|
38
|
+
var version = "0.48.0";
|
|
39
39
|
|
|
40
40
|
//#endregion
|
|
41
41
|
//#region src/lib/interactive-mode.ts
|
|
@@ -22111,6 +22111,109 @@ const renderSigningGradle = ({ keystorePath, storePassword, keyAlias, keyPasswor
|
|
|
22111
22111
|
}
|
|
22112
22112
|
`;
|
|
22113
22113
|
|
|
22114
|
+
//#endregion
|
|
22115
|
+
//#region src/lib/dotenv-file.ts
|
|
22116
|
+
/** Escape a string so it can be embedded as a literal inside a RegExp. */
|
|
22117
|
+
const escapeRegExp = (value) => value.replaceAll(/[.*+?^${}()|[\]\\]/gu, String.raw`\$&`);
|
|
22118
|
+
/**
|
|
22119
|
+
* Set or append `KEY=value` in a `.env` file body, mirroring the line-based
|
|
22120
|
+
* reader used by react-native-config (`dotenv.gradle` on Android,
|
|
22121
|
+
* `BuildDotenvConfig.rb` on iOS): values are written raw and single-line, an
|
|
22122
|
+
* existing key is replaced in place, a new key is appended at the end. Returns
|
|
22123
|
+
* the updated body.
|
|
22124
|
+
*/
|
|
22125
|
+
const setEnvVar = (content, key, value) => {
|
|
22126
|
+
const re = new RegExp(String.raw`^${escapeRegExp(key)}=.*$`, "mu");
|
|
22127
|
+
return re.test(content) ? content.replace(re, `${key}=${value}`) : `${content.replace(/\n*$/u, "")}\n${key}=${value}\n`;
|
|
22128
|
+
};
|
|
22129
|
+
/** Apply a batch of `KEY=value` upserts in order (later entries win on a dup key). */
|
|
22130
|
+
const setEnvVars = (content, entries) => entries.reduce((acc, [key, value]) => setEnvVar(acc, key, value), content);
|
|
22131
|
+
|
|
22132
|
+
//#endregion
|
|
22133
|
+
//#region src/lib/android-version-sync.ts
|
|
22134
|
+
const CODE_LITERAL = /\bversionCode\s+(?<code>\d+)/u;
|
|
22135
|
+
const NAME_LITERAL = /\bversionName\s+(?<quote>["'])(?<name>[^"'\n]*)\k<quote>/u;
|
|
22136
|
+
const CODE_ENV = /\bversionCode\b[^\n]*?\.env\.get\(\s*["'](?<key>[^"']+)["']\s*\)/u;
|
|
22137
|
+
const NAME_ENV = /\bversionName\b[^\n]*?\.env\.get\(\s*["'](?<key>[^"']+)["']\s*\)/u;
|
|
22138
|
+
/**
|
|
22139
|
+
* Materialize one version field: patch a `build.gradle` literal in place, or
|
|
22140
|
+
* collect the referenced `.env` key when the value is `project.env.get(...)`.
|
|
22141
|
+
*/
|
|
22142
|
+
const planField = (gradle, literal, env, value, rewriteLiteral) => {
|
|
22143
|
+
if (literal.test(gradle)) return {
|
|
22144
|
+
gradle: gradle.replace(literal, rewriteLiteral),
|
|
22145
|
+
matched: true
|
|
22146
|
+
};
|
|
22147
|
+
const key = env.exec(gradle)?.groups?.["key"];
|
|
22148
|
+
if (key !== void 0) return {
|
|
22149
|
+
gradle,
|
|
22150
|
+
envKey: [key, value],
|
|
22151
|
+
matched: true
|
|
22152
|
+
};
|
|
22153
|
+
return {
|
|
22154
|
+
gradle,
|
|
22155
|
+
matched: false
|
|
22156
|
+
};
|
|
22157
|
+
};
|
|
22158
|
+
/** Plan both version fields against the build.gradle content. */
|
|
22159
|
+
const planVersions = (gradle, params) => {
|
|
22160
|
+
const envKeys = [];
|
|
22161
|
+
const unresolved = [];
|
|
22162
|
+
let next = gradle;
|
|
22163
|
+
const apply = (value, literal, env, kind) => {
|
|
22164
|
+
if (value === void 0) return;
|
|
22165
|
+
const outcome = planField(next, literal, env, value, kind === "versionCode" ? () => `versionCode ${value}` : (match) => match.replace(NAME_LITERAL, (_full, quote) => `versionName ${quote}${value}${quote}`));
|
|
22166
|
+
next = outcome.gradle;
|
|
22167
|
+
if (outcome.envKey) envKeys.push(outcome.envKey);
|
|
22168
|
+
else if (!outcome.matched) unresolved.push(kind);
|
|
22169
|
+
};
|
|
22170
|
+
apply(params.versionCode, CODE_LITERAL, CODE_ENV, "versionCode");
|
|
22171
|
+
apply(params.versionName, NAME_LITERAL, NAME_ENV, "versionName");
|
|
22172
|
+
return {
|
|
22173
|
+
gradle: next,
|
|
22174
|
+
envKeys,
|
|
22175
|
+
unresolved
|
|
22176
|
+
};
|
|
22177
|
+
};
|
|
22178
|
+
const writeEnvKeys = (envPath, envKeys) => Effect.gen(function* () {
|
|
22179
|
+
const fs = yield* FileSystem.FileSystem;
|
|
22180
|
+
const current = yield* fs.readFileString(envPath).pipe(Effect.orElseSucceed(() => ""));
|
|
22181
|
+
const next = envKeys.reduce((acc, [key, value]) => setEnvVar(acc, key, value), current);
|
|
22182
|
+
yield* fs.writeFileString(envPath, next).pipe(Effect.orElseSucceed(() => void 0));
|
|
22183
|
+
});
|
|
22184
|
+
const reportResult = (params, patchedGradle, envKeys) => {
|
|
22185
|
+
return printHuman(`Applied eas.json version (${[...params.versionName === void 0 ? [] : [`versionName=${params.versionName}`], ...params.versionCode === void 0 ? [] : [`versionCode=${params.versionCode}`]].join(", ")}) to ${[...patchedGradle ? ["build.gradle"] : [], ...envKeys.length === 0 ? [] : [`.env (${envKeys.map(([key]) => key).join(", ")})`]].join(" + ")}`);
|
|
22186
|
+
};
|
|
22187
|
+
/**
|
|
22188
|
+
* Materialize an eas.json Android version / versionCode override into the staged
|
|
22189
|
+
* project so the built APK/AAB matches eas.json. Two shapes are supported:
|
|
22190
|
+
*
|
|
22191
|
+
* - Literal `versionCode` / `versionName` in `android/app/build.gradle` → the
|
|
22192
|
+
* literal is patched in place.
|
|
22193
|
+
* - react-native-config `project.env.get("KEY")` → the referenced key is written
|
|
22194
|
+
* into the staged `.env`, which the dotenv.gradle reader consumes at build time.
|
|
22195
|
+
*
|
|
22196
|
+
* Best-effort and non-fatal: a project whose version is wired some other way is
|
|
22197
|
+
* left untouched with a warning, never failing the build. Expo and custom builds
|
|
22198
|
+
* never reach here (the caller gates on non-Expo, native-strategy builds).
|
|
22199
|
+
*/
|
|
22200
|
+
const applyAndroidVersion = (params) => Effect.gen(function* () {
|
|
22201
|
+
if (params.versionName === void 0 && params.versionCode === void 0) return;
|
|
22202
|
+
const fs = yield* FileSystem.FileSystem;
|
|
22203
|
+
const gradlePath = path.join(params.projectRoot, "android", "app", "build.gradle");
|
|
22204
|
+
const original = yield* fs.readFileString(gradlePath).pipe(Effect.orElseSucceed(() => void 0));
|
|
22205
|
+
if (original === void 0) {
|
|
22206
|
+
yield* printWarn(`Could not read ${gradlePath} to apply the eas.json version override — leaving native version as-is.`);
|
|
22207
|
+
return;
|
|
22208
|
+
}
|
|
22209
|
+
const plan = planVersions(original, params);
|
|
22210
|
+
const patchedGradle = plan.gradle !== original;
|
|
22211
|
+
if (patchedGradle) yield* fs.writeFileString(gradlePath, plan.gradle).pipe(Effect.orElseSucceed(() => void 0));
|
|
22212
|
+
if (plan.envKeys.length > 0) yield* writeEnvKeys(path.join(params.projectRoot, ".env"), plan.envKeys);
|
|
22213
|
+
if (patchedGradle || plan.envKeys.length > 0) yield* reportResult(params, patchedGradle, plan.envKeys);
|
|
22214
|
+
if (plan.unresolved.length > 0) yield* printWarn(`Could not locate ${plan.unresolved.join(" / ")} in android/app/build.gradle (no literal or react-native-config \`project.env.get(...)\` form found) — the built artifact may not reflect the eas.json version.`);
|
|
22215
|
+
});
|
|
22216
|
+
|
|
22114
22217
|
//#endregion
|
|
22115
22218
|
//#region src/lib/string-utils.ts
|
|
22116
22219
|
const capitalize = (value) => {
|
|
@@ -23211,6 +23314,13 @@ const runGradleBuild = (input, commandEnv) => Effect.gen(function* () {
|
|
|
23211
23314
|
const moduleName = input.androidProfile.module ?? "app";
|
|
23212
23315
|
const androidDir = path.join(input.projectRoot, "android");
|
|
23213
23316
|
yield* fixGradlew(androidDir, input.strategy !== "expo");
|
|
23317
|
+
if (input.nativeVersion !== void 0) yield* applyAndroidVersion({
|
|
23318
|
+
projectRoot: input.projectRoot,
|
|
23319
|
+
...compact({
|
|
23320
|
+
versionName: input.nativeVersion.versionName,
|
|
23321
|
+
versionCode: input.nativeVersion.versionCode
|
|
23322
|
+
})
|
|
23323
|
+
});
|
|
23214
23324
|
const credentials = yield* resolveAndroidCredentials(input);
|
|
23215
23325
|
const gradleArgs = credentials === void 0 ? [] : yield* Effect.gen(function* () {
|
|
23216
23326
|
const fs = yield* FileSystem.FileSystem;
|
|
@@ -23949,8 +24059,15 @@ const parseProject$1 = (pbxprojPath) => Effect.try({
|
|
|
23949
24059
|
* spaces, brackets or non-identifier characters needs explicit quoting.
|
|
23950
24060
|
*/
|
|
23951
24061
|
const quote = (value) => `"${value.replaceAll("\"", String.raw`\"`)}"`;
|
|
24062
|
+
/**
|
|
24063
|
+
* Version values (e.g. `6.0.4`, `17`) are normally emitted unquoted in pbxproj.
|
|
24064
|
+
* Keep them bare when they are a safe token to minimize diff noise versus the
|
|
24065
|
+
* committed project; fall back to quoting only for unusual values.
|
|
24066
|
+
*/
|
|
24067
|
+
const SAFE_PBX_TOKEN = /^[A-Za-z0-9._-]+$/u;
|
|
24068
|
+
const pbxValue = (value) => SAFE_PBX_TOKEN.test(value) ? value : quote(value);
|
|
23952
24069
|
const SDK_CONDITIONAL_IDENTITY_KEYS = ["\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\"", "CODE_SIGN_IDENTITY[sdk=iphoneos*]"];
|
|
23953
|
-
const mutateConfig = (project, configUuid, settings) => {
|
|
24070
|
+
const mutateConfig = (project, configUuid, settings, versions) => {
|
|
23954
24071
|
const cfg = project.pbxXCBuildConfigurationSection()[configUuid];
|
|
23955
24072
|
if (!cfg || typeof cfg === "string") return false;
|
|
23956
24073
|
cfg.buildSettings["CODE_SIGN_STYLE"] = "Manual";
|
|
@@ -23959,12 +24076,16 @@ const mutateConfig = (project, configUuid, settings) => {
|
|
|
23959
24076
|
cfg.buildSettings["PROVISIONING_PROFILE_SPECIFIER"] = quote(settings.profileSpecifier);
|
|
23960
24077
|
delete cfg.buildSettings["PROVISIONING_PROFILE"];
|
|
23961
24078
|
for (const key of SDK_CONDITIONAL_IDENTITY_KEYS) delete cfg.buildSettings[key];
|
|
24079
|
+
if (versions?.marketingVersion !== void 0) cfg.buildSettings["MARKETING_VERSION"] = pbxValue(versions.marketingVersion);
|
|
24080
|
+
if (versions?.currentProjectVersion !== void 0) cfg.buildSettings["CURRENT_PROJECT_VERSION"] = pbxValue(versions.currentProjectVersion);
|
|
23962
24081
|
return true;
|
|
23963
24082
|
};
|
|
23964
24083
|
/**
|
|
23965
24084
|
* Write `CODE_SIGN_STYLE=Manual`, `DEVELOPMENT_TEAM`, `CODE_SIGN_IDENTITY`, and
|
|
23966
24085
|
* `PROVISIONING_PROFILE_SPECIFIER` into the specified XCBuildConfiguration
|
|
23967
|
-
* entries of the project under `iosDir`, then serialize back to disk.
|
|
24086
|
+
* entries of the project under `iosDir`, then serialize back to disk. When an
|
|
24087
|
+
* entry carries `versions`, `MARKETING_VERSION` / `CURRENT_PROJECT_VERSION` are
|
|
24088
|
+
* written into the same configuration(s) in the one pass.
|
|
23968
24089
|
*
|
|
23969
24090
|
* Only mutates the main app project — `Pods.xcodeproj` is left untouched. The
|
|
23970
24091
|
* caller is responsible for ensuring each entry's `buildConfigurationUuids`
|
|
@@ -23976,7 +24097,7 @@ const applyTargetSigning = (options) => Effect.gen(function* () {
|
|
|
23976
24097
|
const projectDir = yield* findXcodeProjectDir$1(options.iosDir);
|
|
23977
24098
|
const pbxprojPath = path.join(projectDir, "project.pbxproj");
|
|
23978
24099
|
const project = yield* parseProject$1(pbxprojPath);
|
|
23979
|
-
for (const entry of options.entries) for (const configUuid of entry.buildConfigurationUuids) if (!mutateConfig(project, configUuid, entry.settings)) return yield* new XcodeProjectError({ message: `Build configuration ${configUuid} not found for target "${entry.targetName}" in ${pbxprojPath}.` });
|
|
24100
|
+
for (const entry of options.entries) for (const configUuid of entry.buildConfigurationUuids) if (!mutateConfig(project, configUuid, entry.settings, entry.versions)) return yield* new XcodeProjectError({ message: `Build configuration ${configUuid} not found for target "${entry.targetName}" in ${pbxprojPath}.` });
|
|
23980
24101
|
const serialized = yield* Effect.try({
|
|
23981
24102
|
try: () => project.writeSync(),
|
|
23982
24103
|
catch: (cause) => new XcodeProjectError({ message: `Failed to serialize ${pbxprojPath}: ${cause instanceof Error ? cause.message : String(cause)}` })
|
|
@@ -24139,6 +24260,30 @@ const installProvisioningProfile = ({ profilePath }) => Effect.acquireRelease(Ef
|
|
|
24139
24260
|
installedPath
|
|
24140
24261
|
})));
|
|
24141
24262
|
|
|
24263
|
+
//#endregion
|
|
24264
|
+
//#region src/lib/ios-signing-entries.ts
|
|
24265
|
+
/**
|
|
24266
|
+
* Render the pbxproj signing entries for every installed target. When
|
|
24267
|
+
* `nativeVersion` is provided it is attached to ALL signed targets (app +
|
|
24268
|
+
* extensions): App Store validation rejects a bundled extension whose
|
|
24269
|
+
* CFBundleVersion / CFBundleShortVersionString differs from the host app, so the
|
|
24270
|
+
* version must move on every target together (matches `expo prebuild` and the
|
|
24271
|
+
* prior per-repo sync-version workaround).
|
|
24272
|
+
*
|
|
24273
|
+
* Pure and dependency-free so the build pipeline and its tests share one source
|
|
24274
|
+
* of truth for the entry shape without pulling in the credentials stack.
|
|
24275
|
+
*/
|
|
24276
|
+
const buildSigningEntries = (params) => params.installedTargets.map(({ target, installed }) => ({
|
|
24277
|
+
targetName: target.targetName,
|
|
24278
|
+
buildConfigurationUuids: target.buildConfigurationUuids,
|
|
24279
|
+
settings: {
|
|
24280
|
+
teamId: installed.teamId,
|
|
24281
|
+
signingIdentity: params.signingIdentity,
|
|
24282
|
+
profileSpecifier: installed.name
|
|
24283
|
+
},
|
|
24284
|
+
...params.nativeVersion ? { versions: params.nativeVersion } : {}
|
|
24285
|
+
}));
|
|
24286
|
+
|
|
24142
24287
|
//#endregion
|
|
24143
24288
|
//#region src/lib/post-build-validation.ts
|
|
24144
24289
|
const validateOneBundle = (bundleDir, expectedByBundleId, expectedTeamId) => Effect.gen(function* () {
|
|
@@ -24601,15 +24746,11 @@ const runIosDeviceBuild = (input) => Effect.gen(function* () {
|
|
|
24601
24746
|
const installedTargets = yield* installPerTarget(signedTargets, credentials, input.credentialsSource);
|
|
24602
24747
|
yield* applyTargetSigning({
|
|
24603
24748
|
iosDir,
|
|
24604
|
-
entries:
|
|
24605
|
-
|
|
24606
|
-
|
|
24607
|
-
|
|
24608
|
-
|
|
24609
|
-
signingIdentity: keychain.signingIdentity,
|
|
24610
|
-
profileSpecifier: installed.name
|
|
24611
|
-
}
|
|
24612
|
-
}))
|
|
24749
|
+
entries: buildSigningEntries({
|
|
24750
|
+
installedTargets,
|
|
24751
|
+
signingIdentity: keychain.signingIdentity,
|
|
24752
|
+
nativeVersion: input.nativeVersion
|
|
24753
|
+
})
|
|
24613
24754
|
});
|
|
24614
24755
|
const archivePath = path.join(tempDir, "build.xcarchive");
|
|
24615
24756
|
const archiveCmd = {
|
|
@@ -24748,6 +24889,59 @@ const resolveIosStrategy = (profile, projectType) => {
|
|
|
24748
24889
|
return projectType === "expo" ? "expo" : "xcode";
|
|
24749
24890
|
};
|
|
24750
24891
|
|
|
24892
|
+
//#endregion
|
|
24893
|
+
//#region src/lib/env-materialize.ts
|
|
24894
|
+
/**
|
|
24895
|
+
* Does the staged project consume a root `.env` at native-build time via
|
|
24896
|
+
* react-native-config? Only those projects need env materialization:
|
|
24897
|
+
*
|
|
24898
|
+
* - Expo reads `process.env` / app.config and regenerates native at prebuild.
|
|
24899
|
+
* - A bare project WITHOUT react-native-config reads its config another way
|
|
24900
|
+
* (process.env injection / hardcoded), so writing a stray `.env` there could
|
|
24901
|
+
* shadow unrelated config — leave it untouched.
|
|
24902
|
+
*
|
|
24903
|
+
* react-native-config is always a direct dependency when used, so package.json is
|
|
24904
|
+
* the reliable signal. Mirrors `hasExpoDependency` in detect-project-type.ts; a
|
|
24905
|
+
* missing/unparseable package.json is treated as "no".
|
|
24906
|
+
*/
|
|
24907
|
+
const usesReactNativeConfig = (projectRoot) => Effect.gen(function* () {
|
|
24908
|
+
const text = yield* (yield* FileSystem.FileSystem).readFileString(path.join(projectRoot, "package.json")).pipe(Effect.orElseSucceed(() => ""));
|
|
24909
|
+
if (text.length === 0) return false;
|
|
24910
|
+
const pkg = asRecord(yield* Effect.try(() => JSON.parse(text)).pipe(Effect.orElseSucceed(() => void 0)));
|
|
24911
|
+
const deps = asRecord(pkg?.["dependencies"]);
|
|
24912
|
+
const devDeps = asRecord(pkg?.["devDependencies"]);
|
|
24913
|
+
return deps?.["react-native-config"] !== void 0 || devDeps?.["react-native-config"] !== void 0;
|
|
24914
|
+
});
|
|
24915
|
+
/**
|
|
24916
|
+
* Materialize the decrypted environment into the staged project's `.env` so a
|
|
24917
|
+
* bare react-native-config build reads the SAME values the Expo path gets via
|
|
24918
|
+
* `process.env`. react-native-config reads the `.env` FILE at build time (not
|
|
24919
|
+
* `process.env`), so without this a bare project would ship with whatever `.env`
|
|
24920
|
+
* was committed (or none) regardless of the server's environment.
|
|
24921
|
+
*
|
|
24922
|
+
* Supports both bare shapes:
|
|
24923
|
+
* - WITH react-native-config → values are merged into `.env` (server wins on a
|
|
24924
|
+
* key collision; any committed local-only keys are preserved).
|
|
24925
|
+
* - WITHOUT react-native-config → no-op; the build still gets the env via the
|
|
24926
|
+
* existing process.env injection, so nothing is lost and no stray file appears.
|
|
24927
|
+
*
|
|
24928
|
+
* Best-effort and non-fatal. Expo never reaches here (the caller gates on
|
|
24929
|
+
* non-Expo). An empty env set is a clean no-op, so this is safe to ship before
|
|
24930
|
+
* the server's env-vault is populated.
|
|
24931
|
+
*/
|
|
24932
|
+
const materializeEnvFile = (params) => Effect.gen(function* () {
|
|
24933
|
+
const entries = Object.entries(params.envVars);
|
|
24934
|
+
if (entries.length === 0) return;
|
|
24935
|
+
if (!(yield* usesReactNativeConfig(params.projectRoot))) return;
|
|
24936
|
+
const fs = yield* FileSystem.FileSystem;
|
|
24937
|
+
const envPath = path.join(params.projectRoot, ".env");
|
|
24938
|
+
const current = yield* fs.readFileString(envPath).pipe(Effect.orElseSucceed(() => ""));
|
|
24939
|
+
const next = setEnvVars(current, entries);
|
|
24940
|
+
if (next === current) return;
|
|
24941
|
+
yield* fs.writeFileString(envPath, next).pipe(Effect.orElseSucceed(() => void 0));
|
|
24942
|
+
yield* printHuman(`Materialized ${String(entries.length)} environment variable(s) into .env for react-native-config.`);
|
|
24943
|
+
});
|
|
24944
|
+
|
|
24751
24945
|
//#endregion
|
|
24752
24946
|
//#region src/lib/gradle-config.ts
|
|
24753
24947
|
const isValidAndroidPackageName = Schema.is(AndroidPackageName);
|
|
@@ -24835,6 +25029,11 @@ const runIosPlatformBuild = (input) => Effect.gen(function* () {
|
|
|
24835
25029
|
bundleIdentifier: iosBundleId,
|
|
24836
25030
|
distribution: iosProfile.distribution
|
|
24837
25031
|
}, { freezeCredentials: input.freezeCredentials });
|
|
25032
|
+
const iosOverride = profile.ios.metaOverride;
|
|
25033
|
+
const nativeVersion = input.projectType !== "expo" && (iosOverride?.version !== void 0 || iosOverride?.buildNumber !== void 0) ? compact({
|
|
25034
|
+
marketingVersion: appMeta.appVersion,
|
|
25035
|
+
currentProjectVersion: appMeta.buildNumber
|
|
25036
|
+
}) : void 0;
|
|
24838
25037
|
return {
|
|
24839
25038
|
build: yield* runIosBuild({
|
|
24840
25039
|
api,
|
|
@@ -24850,7 +25049,10 @@ const runIosPlatformBuild = (input) => Effect.gen(function* () {
|
|
|
24850
25049
|
rawOutput: input.rawOutput,
|
|
24851
25050
|
freezeCredentials: input.freezeCredentials,
|
|
24852
25051
|
updateChannel: input.updateChannel,
|
|
24853
|
-
...compact({
|
|
25052
|
+
...compact({
|
|
25053
|
+
customCommand: profile.customCommand?.ios,
|
|
25054
|
+
nativeVersion
|
|
25055
|
+
})
|
|
24854
25056
|
}),
|
|
24855
25057
|
target: isSimulator ? {
|
|
24856
25058
|
platform: "ios",
|
|
@@ -24880,6 +25082,11 @@ const runAndroidPlatformBuild = (input) => Effect.gen(function* () {
|
|
|
24880
25082
|
projectId,
|
|
24881
25083
|
applicationIdentifier
|
|
24882
25084
|
}, { freezeCredentials: input.freezeCredentials });
|
|
25085
|
+
const androidOverride = profile.android.metaOverride;
|
|
25086
|
+
const nativeVersion = input.projectType !== "expo" && (androidOverride?.version !== void 0 || androidOverride?.versionCode !== void 0) ? compact({
|
|
25087
|
+
versionName: appMeta.appVersion,
|
|
25088
|
+
versionCode: appMeta.buildNumber
|
|
25089
|
+
}) : void 0;
|
|
24883
25090
|
return {
|
|
24884
25091
|
build: yield* runAndroidBuild({
|
|
24885
25092
|
api,
|
|
@@ -24895,7 +25102,10 @@ const runAndroidPlatformBuild = (input) => Effect.gen(function* () {
|
|
|
24895
25102
|
strategy,
|
|
24896
25103
|
packageManager: input.packageManager,
|
|
24897
25104
|
updateChannel: input.updateChannel,
|
|
24898
|
-
...compact({
|
|
25105
|
+
...compact({
|
|
25106
|
+
customCommand: profile.customCommand?.android,
|
|
25107
|
+
nativeVersion
|
|
25108
|
+
})
|
|
24899
25109
|
}),
|
|
24900
25110
|
target: androidProfile.format === "aab" ? {
|
|
24901
25111
|
platform: "android",
|
|
@@ -24910,6 +25120,10 @@ const runAndroidPlatformBuild = (input) => Effect.gen(function* () {
|
|
|
24910
25120
|
};
|
|
24911
25121
|
});
|
|
24912
25122
|
const runPlatformBuild = (input) => Effect.gen(function* () {
|
|
25123
|
+
if (input.projectType !== "expo") yield* materializeEnvFile({
|
|
25124
|
+
projectRoot: input.projectRoot,
|
|
25125
|
+
envVars: input.appEnvVars
|
|
25126
|
+
});
|
|
24913
25127
|
return input.platform === "ios" ? yield* runIosPlatformBuild(input) : yield* runAndroidPlatformBuild(input);
|
|
24914
25128
|
});
|
|
24915
25129
|
|
|
@@ -25245,6 +25459,7 @@ const runBuildWorkflow = (options) => Effect.scoped(Effect.gen(function* () {
|
|
|
25245
25459
|
projectType,
|
|
25246
25460
|
appMeta,
|
|
25247
25461
|
envVars: buildEnv,
|
|
25462
|
+
appEnvVars: envVars,
|
|
25248
25463
|
projectId,
|
|
25249
25464
|
projectRoot: staging.projectRoot,
|
|
25250
25465
|
tempDir,
|