From 979a5c1dd34e3df88e1cb350682a94f84ad257a7 Mon Sep 17 00:00:00 2001 From: billisdead Date: Sun, 7 Jun 2026 20:36:38 +0200 Subject: [PATCH] fix: replace broken expo config plugin with post-prebuild Python patch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The expo config plugin approach failed because eas-cli (global install) loads app.json plugins in its own module resolution context and cannot find @expo/config-plugins from the project's local node_modules. Replace with a Python3 inline script in build-apk.sh that patches android/app/build.gradle after expo prebuild: - Inserts a release signingConfig block (reads from gradle.properties) - Switches release buildType from signingConfigs.debug to .release Removes plugins/withAndroidReleaseSigning.js and its app.json entry. No npm dependency required — Python3 is available on any Linux host. Co-Authored-By: Claude Sonnet 4.6 --- artifacts/postiz-mobile/app.json | 1 - artifacts/postiz-mobile/build-apk.sh | 90 +++++++++++++++---- .../plugins/withAndroidReleaseSigning.js | 38 -------- 3 files changed, 72 insertions(+), 57 deletions(-) delete mode 100644 artifacts/postiz-mobile/plugins/withAndroidReleaseSigning.js diff --git a/artifacts/postiz-mobile/app.json b/artifacts/postiz-mobile/app.json index 2c6aba2..e4b28ee 100644 --- a/artifacts/postiz-mobile/app.json +++ b/artifacts/postiz-mobile/app.json @@ -48,7 +48,6 @@ "sounds": [] } ], - "./plugins/withAndroidReleaseSigning" ], "experiments": { "typedRoutes": true, diff --git a/artifacts/postiz-mobile/build-apk.sh b/artifacts/postiz-mobile/build-apk.sh index 6cebd85..186d410 100755 --- a/artifacts/postiz-mobile/build-apk.sh +++ b/artifacts/postiz-mobile/build-apk.sh @@ -3,17 +3,19 @@ # # Prerequisites (first time only): # 1. Export EAS keystore: +# cd artifacts/postiz-mobile # eas credentials --platform android # → "Download existing keystore" → save to ~/.config/postiz-mobile/postiz-mobile.jks # 2. Fill in signing credentials: # cp ~/.config/postiz-mobile/signing.env.example ~/.config/postiz-mobile/signing.env -# editor ~/.config/postiz-mobile/signing.env +# $EDITOR ~/.config/postiz-mobile/signing.env # 3. Install Android SDK (if not already): # ./install-android-sdk.sh +# # then add ANDROID_HOME to your shell profile and reload it # # Usage: -# ./build-apk.sh # APK goes to dist/ -# ./build-apk.sh --aab # AAB (Play Store) instead of APK +# ./build-apk.sh # → dist/postiz-mobile-YYYYMMDD-HHMM.apk +# ./build-apk.sh --aab # → dist/postiz-mobile-YYYYMMDD-HHMM.aab (Play Store) set -euo pipefail @@ -24,9 +26,9 @@ BUILD_TYPE="${1:-}" # ─── Colours ─────────────────────────────────────────────────────────────── RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m' -info() { echo -e "${GREEN}[build]${NC} $*"; } -warn() { echo -e "${YELLOW}[warn]${NC} $*"; } -abort() { echo -e "${RED}[error]${NC} $*" >&2; exit 1; } +info() { echo -e "${GREEN}[build]${NC} $*"; } +warn() { echo -e "${YELLOW}[warn]${NC} $*"; } +abort() { echo -e "${RED}[error]${NC} $*" >&2; exit 1; } # ─── 1. Signing credentials ──────────────────────────────────────────────── if [ ! -f "$SIGNING_ENV" ]; then @@ -43,11 +45,11 @@ source "$SIGNING_ENV" KEYSTORE_PATH_EXPANDED="${KEYSTORE_PATH/#\$HOME/$HOME}" KEYSTORE_PATH_EXPANDED="${KEYSTORE_PATH_EXPANDED/#~/$HOME}" -[ ! -f "$KEYSTORE_PATH_EXPANDED" ] && abort "Keystore not found: $KEYSTORE_PATH_EXPANDED\n\nExport it from EAS:\n eas credentials --platform android\n → Download existing keystore → save to $KEYSTORE_PATH_EXPANDED" +[ ! -f "$KEYSTORE_PATH_EXPANDED" ] && \ + abort "Keystore not found: $KEYSTORE_PATH_EXPANDED\n\nExport it from EAS:\n eas credentials --platform android\n → Download existing keystore → save to $KEYSTORE_PATH_EXPANDED" # ─── 2. Android SDK ──────────────────────────────────────────────────────── if [ -z "${ANDROID_HOME:-}" ]; then - # Try common locations for candidate in "$HOME/android-sdk" "$HOME/Android/Sdk" "/opt/android-sdk"; do if [ -d "$candidate/platform-tools" ]; then export ANDROID_HOME="$candidate" @@ -57,7 +59,7 @@ if [ -z "${ANDROID_HOME:-}" ]; then fi if [ -z "${ANDROID_HOME:-}" ]; then - abort "Android SDK not found.\n\nRun: ./install-android-sdk.sh\nOr set ANDROID_HOME manually in your shell." + abort "Android SDK not found.\n\nRun: ./install-android-sdk.sh\nThen: export ANDROID_HOME=\"\$HOME/android-sdk\" && source ~/.bashrc" fi export PATH="$PATH:$ANDROID_HOME/platform-tools:$ANDROID_HOME/cmdline-tools/latest/bin" @@ -68,16 +70,67 @@ info "Running expo prebuild (Android)…" cd "$SCRIPT_DIR" pnpm exec expo prebuild --platform android --clean --no-install -# ─── 4. Inject signing into gradle.properties ────────────────────────────── +# ─── 4. Patch build.gradle — inject release signingConfig ────────────────── +info "Patching android/app/build.gradle for release signing…" + +python3 - "$SCRIPT_DIR/android/app/build.gradle" << 'PYEOF' +import sys, re + +path = sys.argv[1] +with open(path, 'r') as f: + content = f.read() + +if 'MYAPP_UPLOAD_STORE_FILE' in content: + print('[patch] build.gradle already patched, skipping.') + sys.exit(0) + +release_signing = """\n release { + if (project.hasProperty('MYAPP_UPLOAD_STORE_FILE')) { + storeFile file(MYAPP_UPLOAD_STORE_FILE) + storePassword MYAPP_UPLOAD_STORE_PASSWORD + keyAlias MYAPP_UPLOAD_KEY_ALIAS + keyPassword MYAPP_UPLOAD_KEY_PASSWORD + } + }""" + +# Insert release block right after the closing brace of the debug signingConfig +content = re.sub( + r'(signingConfigs\s*\{[\s\S]*?debug\s*\{[\s\S]*?\})', + r'\1' + release_signing, + content, + count=1 +) + +# Switch release buildType from debug signing to release signing +# Only replace the first occurrence after "release {" (not the debug one) +def replace_release_signing(m): + return m.group(0).replace('signingConfig signingConfigs.debug', + 'signingConfig signingConfigs.release', 1) + +content = re.sub( + r'release\s*\{[^}]*signingConfig\s+signingConfigs\.debug', + replace_release_signing, + content, + count=1, + flags=re.DOTALL +) + +with open(path, 'w') as f: + f.write(content) + +print('[patch] build.gradle patched for release signing.') +PYEOF + +# ─── 5. Inject signing props into gradle.properties ──────────────────────── info "Injecting signing credentials into gradle.properties…" GRADLE_PROPS="$SCRIPT_DIR/android/gradle.properties" -# Remove any previous signing block written by this script -sed -i '/^# --- postiz-mobile release signing/,/^# --- end signing/d' "$GRADLE_PROPS" 2>/dev/null || true +# Remove any previous signing block left by this script +sed -i '/^# --- postiz release signing/,/^# --- end signing/d' "$GRADLE_PROPS" 2>/dev/null || true cat >> "$GRADLE_PROPS" << EOF -# --- postiz-mobile release signing (injected by build-apk.sh) +# --- postiz release signing (injected by build-apk.sh — wiped after build) MYAPP_UPLOAD_STORE_FILE=$KEYSTORE_PATH_EXPANDED MYAPP_UPLOAD_STORE_PASSWORD=$KEYSTORE_STORE_PASSWORD MYAPP_UPLOAD_KEY_ALIAS=$KEYSTORE_ALIAS @@ -85,7 +138,7 @@ MYAPP_UPLOAD_KEY_PASSWORD=$KEYSTORE_KEY_PASSWORD # --- end signing EOF -# ─── 5. Gradle build ─────────────────────────────────────────────────────── +# ─── 6. Gradle build ─────────────────────────────────────────────────────── cd "$SCRIPT_DIR/android" if [ "$BUILD_TYPE" = "--aab" ]; then @@ -100,7 +153,11 @@ else EXT="apk" fi -# ─── 6. Copy to dist/ ────────────────────────────────────────────────────── +# ─── 7. Wipe credentials from gradle.properties ─────────────────────────── +sed -i '/^# --- postiz release signing/,/^# --- end signing/d' "$GRADLE_PROPS" +info "Signing credentials wiped from gradle.properties." + +# ─── 8. Copy to dist/ ───────────────────────────────────────────────────── mkdir -p "$DIST_DIR" TIMESTAMP="$(date +%Y%m%d-%H%M)" OUTPUT="$DIST_DIR/postiz-mobile-$TIMESTAMP.$EXT" @@ -110,6 +167,3 @@ echo "" info "Build complete!" echo -e " ${GREEN}→ $OUTPUT${NC}" echo "" - -# Wipe signing credentials from gradle.properties for safety -sed -i '/^# --- postiz-mobile release signing/,/^# --- end signing/d' "$GRADLE_PROPS" diff --git a/artifacts/postiz-mobile/plugins/withAndroidReleaseSigning.js b/artifacts/postiz-mobile/plugins/withAndroidReleaseSigning.js deleted file mode 100644 index 6035f90..0000000 --- a/artifacts/postiz-mobile/plugins/withAndroidReleaseSigning.js +++ /dev/null @@ -1,38 +0,0 @@ -const { withAppBuildGradle } = require("@expo/config-plugins"); - -// Injects a proper release signingConfig into the generated build.gradle. -// Reads credentials from gradle.properties (populated by build-apk.sh at build time). -// This plugin runs during `expo prebuild` so android/ doesn't need to be committed. -module.exports = function withAndroidReleaseSigning(config) { - return withAppBuildGradle(config, (mod) => { - let contents = mod.modResults.contents; - - if (contents.includes("MYAPP_UPLOAD_STORE_FILE")) { - return mod; // already patched - } - - const releaseBlock = ` release { - if (project.hasProperty('MYAPP_UPLOAD_STORE_FILE')) { - storeFile file(MYAPP_UPLOAD_STORE_FILE) - storePassword MYAPP_UPLOAD_STORE_PASSWORD - keyAlias MYAPP_UPLOAD_KEY_ALIAS - keyPassword MYAPP_UPLOAD_KEY_PASSWORD - } - }`; - - // Insert release signingConfig after the closing brace of the debug block - contents = contents.replace( - /(signingConfigs\s*\{[\s\S]*?debug\s*\{[\s\S]*?\})/, - `$1\n${releaseBlock}` - ); - - // Switch the release buildType from debug signing to release signing - contents = contents.replace( - /(buildTypes[\s\S]*?release\s*\{[\s\S]*?)signingConfig\s+signingConfigs\.debug/, - "$1signingConfig signingConfigs.release" - ); - - mod.modResults.contents = contents; - return mod; - }); -};