mirror of
https://github.com/getpaseo/paseo.git
synced 2026-11-01 14:12:51 +00:00
Run Expo prebuild and serialized Gradle directly instead of passing signing credentials through the local EAS payload. Verify the finished APK against the production signing fingerprint before upload.
228 lines
6.4 KiB
JavaScript
228 lines
6.4 KiB
JavaScript
const fs = require("node:fs");
|
|
const path = require("node:path");
|
|
const pkg = require("./package.json");
|
|
const withFdroidAutolinking = require("./plugins/with-fdroid-autolinking");
|
|
const appVariant = process.env.APP_VARIANT ?? "production";
|
|
const isFdroidBuild = process.env.PASEO_FDROID_BUILD === "1";
|
|
|
|
const buildProfile = isFdroidBuild
|
|
? {
|
|
androidPermissions: [
|
|
"RECORD_AUDIO",
|
|
"android.permission.RECORD_AUDIO",
|
|
"android.permission.MODIFY_AUDIO_SETTINGS",
|
|
],
|
|
cameraPlugins: [],
|
|
fdroidPlugins: [withFdroidAutolinking],
|
|
notificationPlugins: [],
|
|
updates: { enabled: false },
|
|
}
|
|
: {
|
|
androidPermissions: [
|
|
"RECORD_AUDIO",
|
|
"android.permission.RECORD_AUDIO",
|
|
"android.permission.MODIFY_AUDIO_SETTINGS",
|
|
"CAMERA",
|
|
"android.permission.CAMERA",
|
|
],
|
|
cameraPlugins: [
|
|
[
|
|
"expo-camera",
|
|
{
|
|
cameraPermission:
|
|
"Allow $(PRODUCT_NAME) to access your camera to scan pairing QR codes.",
|
|
},
|
|
],
|
|
],
|
|
fdroidPlugins: [],
|
|
notificationPlugins: [
|
|
[
|
|
"expo-notifications",
|
|
{
|
|
icon: "./assets/images/notification-icon.png",
|
|
color: "#20744A",
|
|
},
|
|
],
|
|
],
|
|
updates: {},
|
|
};
|
|
|
|
function getNativeBuildVersionCode(version) {
|
|
const match = /^(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/.exec(version);
|
|
if (!match) {
|
|
throw new Error(`Cannot derive Android versionCode from non-semver version: ${version}`);
|
|
}
|
|
|
|
const [, majorText, minorText, patchText] = match;
|
|
const major = Number(majorText);
|
|
const minor = Number(minorText);
|
|
const patch = Number(patchText);
|
|
|
|
if (minor > 999 || patch > 999) {
|
|
throw new Error(`Cannot derive collision-free Android versionCode from version: ${version}`);
|
|
}
|
|
|
|
const versionCode = major * 1_000_000 + minor * 1_000 + patch;
|
|
|
|
if (!Number.isSafeInteger(versionCode) || versionCode <= 0 || versionCode > 2_100_000_000) {
|
|
throw new Error(`Derived Android versionCode is out of range: ${versionCode}`);
|
|
}
|
|
|
|
return versionCode;
|
|
}
|
|
|
|
function resolveSecretFile(params) {
|
|
const fromEnv = process.env[params.envKey];
|
|
if (typeof fromEnv === "string" && fromEnv.trim().length > 0) {
|
|
return fromEnv.trim();
|
|
}
|
|
|
|
const fallbackAbsolutePath = path.resolve(__dirname, params.fallbackRelativePath);
|
|
if (fs.existsSync(fallbackAbsolutePath)) {
|
|
return params.fallbackRelativePath;
|
|
}
|
|
|
|
return undefined;
|
|
}
|
|
|
|
const variants = {
|
|
production: {
|
|
name: "Paseo",
|
|
packageId: "sh.paseo",
|
|
googleServicesFile: resolveSecretFile({
|
|
envKey: "GOOGLE_SERVICES_FILE_PROD",
|
|
fallbackRelativePath: "./.secrets/google-services.prod.json",
|
|
}),
|
|
googleServiceInfoPlist: resolveSecretFile({
|
|
envKey: "GOOGLE_SERVICE_INFO_PLIST_PROD",
|
|
fallbackRelativePath: "./.secrets/GoogleService-Info.prod.plist",
|
|
}),
|
|
},
|
|
development: {
|
|
name: "Paseo Debug",
|
|
packageId: "sh.paseo.debug",
|
|
googleServicesFile: resolveSecretFile({
|
|
envKey: "GOOGLE_SERVICES_FILE_DEBUG",
|
|
fallbackRelativePath: "./.secrets/google-services.debug.json",
|
|
}),
|
|
googleServiceInfoPlist: resolveSecretFile({
|
|
envKey: "GOOGLE_SERVICE_INFO_PLIST_DEBUG",
|
|
fallbackRelativePath: "./.secrets/GoogleService-Info.debug.plist",
|
|
}),
|
|
},
|
|
};
|
|
|
|
const variant = variants[appVariant] ?? variants.production;
|
|
const nativeBuildVersionCode = getNativeBuildVersionCode(pkg.version);
|
|
|
|
export default {
|
|
expo: {
|
|
name: variant.name,
|
|
slug: "voice-mobile",
|
|
version: pkg.version,
|
|
orientation: "portrait",
|
|
icon: "./assets/images/icon.png",
|
|
scheme: "paseo",
|
|
userInterfaceStyle: "automatic",
|
|
newArchEnabled: true,
|
|
runtimeVersion: {
|
|
policy: "appVersion",
|
|
},
|
|
updates: {
|
|
url: "https://u.expo.dev/0e7f65ce-0367-46c8-a238-2b65963d235a",
|
|
...(process.env.EXPO_UPDATES_CHANNEL
|
|
? {
|
|
requestHeaders: {
|
|
"expo-channel-name": process.env.EXPO_UPDATES_CHANNEL,
|
|
},
|
|
}
|
|
: {}),
|
|
...buildProfile.updates,
|
|
},
|
|
ios: {
|
|
supportsTablet: true,
|
|
infoPlist: {
|
|
NSMicrophoneUsageDescription: "This app needs access to the microphone for voice commands.",
|
|
ITSAppUsesNonExemptEncryption: false,
|
|
},
|
|
bundleIdentifier: variant.packageId,
|
|
...(variant.googleServiceInfoPlist
|
|
? { googleServicesFile: variant.googleServiceInfoPlist }
|
|
: {}),
|
|
buildNumber: String(nativeBuildVersionCode),
|
|
},
|
|
android: {
|
|
adaptiveIcon: {
|
|
backgroundColor: "#000000",
|
|
foregroundImage: "./assets/images/android-icon-foreground.png",
|
|
},
|
|
edgeToEdgeEnabled: true,
|
|
predictiveBackGestureEnabled: false,
|
|
softwareKeyboardLayoutMode: "resize",
|
|
// Allow HTTP connections for local network hosts (required for release builds)
|
|
usesCleartextTraffic: true,
|
|
permissions: buildProfile.androidPermissions,
|
|
package: variant.packageId,
|
|
versionCode: nativeBuildVersionCode,
|
|
...(variant.googleServicesFile ? { googleServicesFile: variant.googleServicesFile } : {}),
|
|
},
|
|
web: {
|
|
output: "single",
|
|
favicon: "./assets/images/favicon.png",
|
|
},
|
|
autolinking: {
|
|
searchPaths: ["../../node_modules", "./node_modules"],
|
|
},
|
|
plugins: [
|
|
"expo-router",
|
|
...buildProfile.cameraPlugins,
|
|
[
|
|
"expo-splash-screen",
|
|
{
|
|
image: "./assets/images/splash-icon.png",
|
|
imageWidth: 200,
|
|
resizeMode: "contain",
|
|
backgroundColor: "#ffffff",
|
|
dark: {
|
|
backgroundColor: "#000000",
|
|
},
|
|
},
|
|
],
|
|
...buildProfile.notificationPlugins,
|
|
"expo-audio",
|
|
[
|
|
"expo-gradle-jvmargs",
|
|
{
|
|
xmx: "4096m",
|
|
maxMetaspace: "1024m",
|
|
},
|
|
],
|
|
[
|
|
"expo-build-properties",
|
|
{
|
|
android: {
|
|
minSdkVersion: 29,
|
|
kotlinVersion: "2.1.20",
|
|
// Allow HTTP connections for local network hosts in release builds
|
|
usesCleartextTraffic: true,
|
|
},
|
|
},
|
|
],
|
|
...buildProfile.fdroidPlugins,
|
|
],
|
|
experiments: {
|
|
typedRoutes: true,
|
|
reactCompiler: true,
|
|
autolinkingModuleResolution: true,
|
|
},
|
|
extra: {
|
|
fdroidBuild: isFdroidBuild,
|
|
router: {},
|
|
eas: {
|
|
projectId: "0e7f65ce-0367-46c8-a238-2b65963d235a",
|
|
},
|
|
},
|
|
owner: "getpaseo",
|
|
},
|
|
};
|