feat: Refactor keystore decoding to Python for improved error handling and normalization

This commit is contained in:
2026-04-08 17:45:32 +07:00
parent 8195887d3c
commit 080afb7e8c
+53 -10
View File
@@ -68,17 +68,60 @@ jobs:
if [ -n "${ANDROID_KEYSTORE_BASE64}" ] && [ -n "${ANDROID_KEYSTORE_PASSWORD}" ] && [ -n "${ANDROID_KEY_ALIAS}" ] && [ -n "${ANDROID_KEY_PASSWORD}" ]; then if [ -n "${ANDROID_KEYSTORE_BASE64}" ] && [ -n "${ANDROID_KEYSTORE_PASSWORD}" ] && [ -n "${ANDROID_KEY_ALIAS}" ] && [ -n "${ANDROID_KEY_PASSWORD}" ]; then
echo "Preparing release keystore from secrets" echo "Preparing release keystore from secrets"
CLEAN_B64="$(printf '%s' "${ANDROID_KEYSTORE_BASE64}" | tr -d '[:space:]')" if ! python3 - <<'PY'
if [ -z "${CLEAN_B64}" ]; then import base64
echo "ANDROID_KEYSTORE_BASE64 is empty after trimming whitespace" import os
exit 1 import re
fi import sys
if ! printf '%s' "${CLEAN_B64}" | base64 --decode > android/release.keystore 2>/tmp/keystore_decode_err; then s = os.environ.get("ANDROID_KEYSTORE_BASE64", "")
echo "Failed to decode ANDROID_KEYSTORE_BASE64" if not s:
echo "Tip: store raw base64 one-line output from: base64 < release.jks | tr -d '\\n'" print("ANDROID_KEYSTORE_BASE64 is empty")
echo "Decode error:" sys.exit(1)
cat /tmp/keystore_decode_err
# Normalize common copy/paste formats.
s = s.strip().strip('"').strip("'")
s = s.replace("\\n", "")
s = re.sub(r"^data:[^,]*,", "", s)
s = re.sub(r"\s+", "", s)
if not s:
print("ANDROID_KEYSTORE_BASE64 is empty after normalization")
sys.exit(1)
def try_decode(value: str, urlsafe: bool, validate: bool):
value = value + ("=" * (-len(value) % 4))
if urlsafe:
value = value.replace("-", "+").replace("_", "/")
return base64.b64decode(value, validate=validate)
decoded = None
errors = []
for urlsafe in (False, True):
for validate in (True, False):
try:
decoded = try_decode(s, urlsafe=urlsafe, validate=validate)
if decoded:
break
except Exception as e:
errors.append(str(e))
if decoded:
break
if not decoded:
print("Failed to decode ANDROID_KEYSTORE_BASE64")
print("Tip: generate with: base64 < release.jks | tr -d '\\n'")
if errors:
print("Last decode error:", errors[-1])
sys.exit(1)
with open("android/release.keystore", "wb") as f:
f.write(decoded)
print(f"Decoded keystore bytes: {len(decoded)}")
PY
then
echo "Keystore decoding failed"
exit 1 exit 1
fi fi