fix(ci): use explicit echo blocks instead of heredocs to prevent leading whitespace in gradle.properties
Some checks failed
Frontend CI / build-and-push-web (push) Has been cancelled
Frontend CI / ota (android) (push) Has been cancelled
Frontend CI / ota (ios) (push) Has been cancelled
Frontend CI / build-android-apk (push) Successful in 45m59s

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.
This commit is contained in:
lafay
2026-06-18 15:37:56 +08:00
parent 1018cd7ea2
commit c1f8acd4fc

View File

@@ -133,43 +133,47 @@ 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: |