From c1f8acd4fcdac96a1d9daf11c41248590915f63b Mon Sep 17 00:00:00 2001 From: lafay <2021211506@stu.hit.edu.cn> Date: Thu, 18 Jun 2026 15:37:56 +0800 Subject: [PATCH] fix(ci): use explicit echo blocks instead of heredocs to prevent leading whitespace in gradle.properties The heredoc approach (`cat >> file << EOF`) was introducing leading whitespace to each line, causing Gradle to treat whitespace as part of property keys. This made hasProperty() return false for signingConfig values, breaking release builds. The fix uses explicit echo blocks that write column-0 strings without indentation artifacts. --- .gitea/workflows/build.yml | 60 ++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml index c8390e5..e5a6154 100644 --- a/.gitea/workflows/build.yml +++ b/.gitea/workflows/build.yml @@ -133,47 +133,51 @@ jobs: # Decode Android signing keystore echo "${{ secrets.ANDROID_KEYSTORE_BASE64 }}" | base64 -d > app/withyou-release-key.keystore - # Append signing properties to gradle.properties (secrets appended after prebuild for better cache hit rate) - cat >> gradle.properties << 'SIGNING_PROPS' - MYAPP_UPLOAD_STORE_FILE=withyou-release-key.keystore - MYAPP_UPLOAD_STORE_PASSWORD=${{ secrets.ANDROID_KEYSTORE_PASSWORD }} - MYAPP_UPLOAD_KEY_ALIAS=withyou-key - MYAPP_UPLOAD_KEY_PASSWORD=${{ secrets.ANDROID_KEY_PASSWORD }} - SIGNING_PROPS + # Append signing properties to gradle.properties (secrets appended after prebuild for better cache hit rate). + # IMPORTANT: each echo line writes a column-0 string to gradle.properties — gradle.properties keys + # cannot have leading whitespace (Gradle treats leading whitespace as part of the key name and + # hasProperty() then returns false, breaking release signing — see app/build.gradle signingConfigs.release). + # NB: this block runs with `set -e` by default; if any echo fails the step aborts. + { + echo "MYAPP_UPLOAD_STORE_FILE=withyou-release-key.keystore" + echo "MYAPP_UPLOAD_STORE_PASSWORD=${{ secrets.ANDROID_KEYSTORE_PASSWORD }}" + echo "MYAPP_UPLOAD_KEY_ALIAS=withyou-key" + echo "MYAPP_UPLOAD_KEY_PASSWORD=${{ secrets.ANDROID_KEY_PASSWORD }}" + } >> gradle.properties # CI build tuning (low-memory container): force single-worker, reduce JVM heap, # plus restore properties that prebuild does NOT generate but the build needs. - cat >> gradle.properties << 'CI_PROPS' - org.gradle.daemon=false - org.gradle.parallel=false - org.gradle.configureondemand=false - org.gradle.workers.max=1 - org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=1g -XX:+UseG1GC -XX:ReservedCodeCacheSize=256m -XX:+HeapDumpOnOutOfMemoryError - kotlin.daemon.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=1g -XX:+UseG1GC -XX:ReservedCodeCacheSize=256m - ndkVersion=27.1.12297006 - systemProp.org.gradle.internal.http.connectionTimeout=30000 - systemProp.org.gradle.internal.http.socketTimeout=30000 - # ExpoAutolinkingPlugin requires this; without it Gradle calls - # `node ... mirror-kotlin-inline-modules --watched-directories-serialized ''` - # and node JSON.parse('') throws SyntaxError, exiting 1. - # See ExpoAutolinkingPlugin.kt:51 (findProperty fallback to emptyList) - # and ExpoAutolinkingPlugin.kt:67 (passes value to node as-is). - expo.inlineModules.watchedDirectories=[] - CI_PROPS + { + echo "org.gradle.daemon=false" + echo "org.gradle.parallel=false" + echo "org.gradle.configureondemand=false" + echo "org.gradle.workers.max=1" + echo "org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=1g -XX:+UseG1GC -XX:ReservedCodeCacheSize=256m -XX:+HeapDumpOnOutOfMemoryError" + echo "kotlin.daemon.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=1g -XX:+UseG1GC -XX:ReservedCodeCacheSize=256m" + echo "ndkVersion=27.1.12297006" + echo "systemProp.org.gradle.internal.http.connectionTimeout=30000" + echo "systemProp.org.gradle.internal.http.socketTimeout=30000" + # ExpoAutolinkingPlugin requires this; without it Gradle calls + # `node ... mirror-kotlin-inline-modules --watched-directories-serialized ''` + # and node JSON.parse('') throws SyntaxError, exiting 1. + # See ExpoAutolinkingPlugin.kt:51 (findProperty fallback to emptyList) + # and ExpoAutolinkingPlugin.kt:67 (passes value to node as-is). + echo "expo.inlineModules.watchedDirectories=[]" + } >> gradle.properties # Verify signing config in app/build.gradle echo "=== app/build.gradle signing section ===" grep -A 20 'signingConfigs' app/build.gradle || echo "signingConfigs not found" - # Diagnostic: dump full gradle.properties + verify expo.inlineModules property + # Diagnostic: dump full gradle.properties + verify the signing property is readable echo "=== gradle.properties (final) ===" cat gradle.properties - echo "=== expo.inlineModules check ===" - grep -c '^expo\.inlineModules\.watchedDirectories=' gradle.properties || echo "MISSING expo.inlineModules.watchedDirectories" + echo "=== MYAPP_UPLOAD_STORE_FILE check ===" + grep -c '^MYAPP_UPLOAD_STORE_FILE=' gradle.properties || echo "MISSING MYAPP_UPLOAD_STORE_FILE (column 0)" - name: Build Android release APK (arm64 only) run: | - cd android + cd android chmod +x gradlew taskset -c 0-7 ./gradlew :app:assembleRelease -PreactNativeArchitectures=arm64-v8a --max-workers=1 --stacktrace --info -Dkotlin.daemon.jvm.options="-Xmx2g,XX:MaxMetaspaceSize=1g" 2>&1 | tee gradle-build.log echo "===== Last 200 lines of build log ====="