Files
IdP/tauri_app/docker/ensure-android-keystore.sh
2026-07-02 16:40:04 +03:00

146 lines
4.7 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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}" <<EOF
# Сгенерировано $(date -u +"%Y-%m-%dT%H:%M:%SZ") — храните в безопасном месте.
ANDROID_KEYSTORE_FILE=${KEYSTORE_FILE}
ANDROID_KEY_ALIAS=${KEY_ALIAS}
ANDROID_KEYSTORE_PASSWORD=${password}
ANDROID_KEY_PASSWORD=${password}
EOF
chmod 600 "${CREDENTIALS_FILE}" || true
cat > "${KEYSTORE_PROPS_TEMPLATE}" <<EOF
storePassword=${password}
keyPassword=${password}
keyAlias=${KEY_ALIAS}
storeFile=${KEYSTORE_FILE}
EOF
chmod 600 "${KEYSTORE_PROPS_TEMPLATE}" || true
}
validate_keystore() {
local store_password="$1"
local key_password="$2"
[[ -n "${store_password}" ]] || return 1
[[ -f "${KEYSTORE_FILE}" ]] || return 1
keytool -list \
-keystore "${KEYSTORE_FILE}" \
-storepass "${store_password}" \
-alias "${KEY_ALIAS}" >/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 успешно создан и проверен"