#!/usr/bin/env bash # Создаёт и проверяет release keystore для подписи APK. set -euo pipefail SECRETS_DIR="${ANDROID_SECRETS_DIR:-/workspace/tauri_app/.secrets}" KEYSTORE_FILE="${ANDROID_KEYSTORE_FILE:-${SECRETS_DIR}/lendry-id-release.keystore}" KEY_ALIAS="${ANDROID_KEY_ALIAS:-lendry-id}" CREDENTIALS_FILE="${SECRETS_DIR}/signing-credentials.env" KEYSTORE_PROPS_TEMPLATE="${SECRETS_DIR}/keystore.properties.template" FORCE_REGENERATE="${ANDROID_KEYSTORE_FORCE_REGENERATE:-0}" mkdir -p "${SECRETS_DIR}" chmod 700 "${SECRETS_DIR}" || true read_credentials() { STORE_PASSWORD="" KEY_PASSWORD="" if [[ -f "${CREDENTIALS_FILE}" ]]; then # shellcheck disable=SC1090 source "${CREDENTIALS_FILE}" STORE_PASSWORD="${ANDROID_KEYSTORE_PASSWORD:-}" KEY_PASSWORD="${ANDROID_KEY_PASSWORD:-${ANDROID_KEYSTORE_PASSWORD:-}}" elif [[ -f "${KEYSTORE_PROPS_TEMPLATE}" ]]; then STORE_PASSWORD="$(grep -E '^storePassword=' "${KEYSTORE_PROPS_TEMPLATE}" | head -n1 | cut -d= -f2- || true)" KEY_PASSWORD="$(grep -E '^keyPassword=' "${KEYSTORE_PROPS_TEMPLATE}" | head -n1 | cut -d= -f2- || true)" KEY_PASSWORD="${KEY_PASSWORD:-${STORE_PASSWORD}}" fi } write_credentials_files() { local password="$1" cat > "${CREDENTIALS_FILE}" < "${KEYSTORE_PROPS_TEMPLATE}" </dev/null 2>&1 || return 1 # Для JKS/PKCS12 у Gradle storePassword и keyPassword должны совпадать. if [[ "${key_password}" != "${store_password}" ]]; then return 1 fi return 0 } backup_broken_keystore() { local backup_dir="${SECRETS_DIR}/backup-$(date +%Y%m%d-%H%M%S)" mkdir -p "${backup_dir}" for file in "${KEYSTORE_FILE}" "${CREDENTIALS_FILE}" "${KEYSTORE_PROPS_TEMPLATE}"; do if [[ -f "${file}" ]]; then cp "${file}" "${backup_dir}/" fi done echo "==> Старые файлы подписи сохранены в ${backup_dir}" } gen_secret() { if command -v openssl >/dev/null 2>&1; then openssl rand -hex 16 else date +%s%N | sha256sum | awk '{print substr($1,1,32)}' fi } create_keystore() { local password="$1" if ! command -v keytool >/dev/null 2>&1; then echo "keytool не найден — нужен JDK для генерации keystore" >&2 exit 1 fi rm -f "${KEYSTORE_FILE}" echo "==> Генерация release keystore для подписи APK..." # JKS + один пароль — максимально совместимо с Android Gradle signing. keytool -genkeypair -v \ -storetype JKS \ -keystore "${KEYSTORE_FILE}" \ -alias "${KEY_ALIAS}" \ -keyalg RSA \ -keysize 2048 \ -validity 10000 \ -storepass "${password}" \ -keypass "${password}" \ -dname "CN=Lendry ID, OU=Mobile, O=Lendry, C=RU" chmod 600 "${KEYSTORE_FILE}" || true write_credentials_files "${password}" echo "==> Keystore создан: ${KEYSTORE_FILE}" echo "==> Пароли сохранены: ${CREDENTIALS_FILE}" } if [[ "${FORCE_REGENERATE}" == "1" && -f "${KEYSTORE_FILE}" ]]; then backup_broken_keystore rm -f "${KEYSTORE_FILE}" "${CREDENTIALS_FILE}" "${KEYSTORE_PROPS_TEMPLATE}" fi if [[ -f "${KEYSTORE_FILE}" ]]; then read_credentials if validate_keystore "${STORE_PASSWORD}" "${KEY_PASSWORD}"; then write_credentials_files "${STORE_PASSWORD}" echo "==> Android keystore проверен: ${KEYSTORE_FILE}" exit 0 fi echo "==> Keystore повреждён или пароли не совпадают — пересоздаём release keystore" >&2 backup_broken_keystore rm -f "${KEYSTORE_FILE}" "${CREDENTIALS_FILE}" "${KEYSTORE_PROPS_TEMPLATE}" fi create_keystore "$(gen_secret)" if ! validate_keystore "$(grep -E '^storePassword=' "${KEYSTORE_PROPS_TEMPLATE}" | cut -d= -f2-)" "$(grep -E '^keyPassword=' "${KEYSTORE_PROPS_TEMPLATE}" | cut -d= -f2-)"; then echo "Не удалось проверить только что созданный keystore" >&2 exit 1 fi echo "==> Keystore успешно создан и проверен"