Files
memory/release.sh

306 lines
8.5 KiB
Bash
Executable File
Raw Permalink 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.
#!/bin/bash
# Memory App 发布脚本
# 功能:自动递增版本号、编译 APK、上传到 R2、更新服务器版本信息
set -e
# ============ 配置区域 ============
# R2 配置
R2_ACCOUNT_ID="ebf33b5ee4eb26f32af0c6e06102e000"
R2_ACCESS_KEY_ID="8acbc8a9386d60d0e8dac6bd8165c618"
R2_ACCESS_KEY_SECRET="72935e23b5b4be8fda99008e75285e8ac778f8926656c42780b25785bb149443"
R2_BUCKET_NAME="memory"
R2_PUBLIC_URL="https://cdn.amos.us.kg"
# API 配置
API_BASE_URL="https://x.amos.us.kg/api"
# 服务器配置
SERVER_HOST="95.181.190.226"
SERVER_PORT="33"
SERVER_USER="root"
SERVER_PASSWORD="xiaobiao."
SERVER_PROJECT_PATH="/amos/memory"
# 签名配置
KEYSTORE_FILE="release.keystore"
KEYSTORE_PASSWORD="memory123"
KEY_ALIAS="memory"
KEY_PASSWORD="memory123"
# ============ 函数定义 ============
# 获取当前版本号
get_current_version() {
grep "versionName" android/app/build.gradle.kts | head -1 | sed 's/.*"\(.*\)".*/\1/'
}
# 获取当前版本代码
get_current_version_code() {
grep "versionCode" android/app/build.gradle.kts | head -1 | sed 's/[^0-9]*//g'
}
# 递增版本号 (1.1.9 -> 1.2.0, 1.1.0 -> 1.1.1)
increment_version() {
local version=$1
local major=$(echo $version | cut -d. -f1)
local minor=$(echo $version | cut -d. -f2)
local patch=$(echo $version | cut -d. -f3)
patch=$((patch + 1))
if [ $patch -ge 10 ]; then
patch=0
minor=$((minor + 1))
if [ $minor -ge 10 ]; then
minor=0
major=$((major + 1))
fi
fi
echo "${major}.${minor}.${patch}"
}
# 更新 build.gradle.kts 中的版本号
update_version_in_gradle() {
local new_version=$1
local new_code=$2
sed -i '' "s/versionCode = [0-9]*/versionCode = ${new_code}/" android/app/build.gradle.kts
sed -i '' "s/versionName = \"[^\"]*\"/versionName = \"${new_version}\"/" android/app/build.gradle.kts
sed -i '' "s/VERSION_CODE\", \"[0-9]*\"/VERSION_CODE\", \"${new_code}\"/" android/app/build.gradle.kts
}
# 编译 Docker 镜像并导出
build_docker() {
echo "🐳 编译 Docker 镜像..."
cd server
docker build --platform linux/amd64 -t memory-server:latest .
docker save memory-server:latest -o memory-server.tar
cd ..
echo "✅ Docker 镜像已导出到 server/memory-server.tar"
}
# 部署 Docker 镜像到服务器
deploy_docker() {
echo "🚀 部署 Docker 镜像到服务器..."
# 上传镜像到服务器
echo "📤 上传镜像文件..."
sshpass -p "${SERVER_PASSWORD}" scp -P ${SERVER_PORT} -o StrictHostKeyChecking=no server/memory-server.tar ${SERVER_USER}@${SERVER_HOST}:${SERVER_PROJECT_PATH}/
# 在服务器上加载镜像并重启
echo "🔄 加载镜像并重启服务..."
sshpass -p "${SERVER_PASSWORD}" ssh -p ${SERVER_PORT} -o StrictHostKeyChecking=no ${SERVER_USER}@${SERVER_HOST} << EOF
cd ${SERVER_PROJECT_PATH}
docker load -i memory-server.tar
docker compose down
docker compose up -d
# 清理旧镜像
echo "🧹 清理旧镜像..."
docker image prune -f
# 删除镜像文件
rm -f memory-server.tar
echo "✅ 服务已重启"
EOF
echo "✅ 部署完成!"
}
# 编译 APK
build_apk() {
echo "📦 编译 APK..."
cd android
KEYSTORE_FILE=$KEYSTORE_FILE \
KEYSTORE_PASSWORD=$KEYSTORE_PASSWORD \
KEY_ALIAS=$KEY_ALIAS \
KEY_PASSWORD=$KEY_PASSWORD \
gradle assembleRelease --quiet
cd ..
}
# 上传到 R2
upload_to_r2() {
local version=$1
local apk_path="android/app/build/outputs/apk/release/app-release.apk"
local remote_path="releases/memory-${version}.apk"
echo "☁️ 上传到 R2..."
# 使用 AWS CLI 上传 (需要配置 AWS CLI)
AWS_ACCESS_KEY_ID=$R2_ACCESS_KEY_ID \
AWS_SECRET_ACCESS_KEY=$R2_ACCESS_KEY_SECRET \
aws s3 cp "$apk_path" "s3://${R2_BUCKET_NAME}/${remote_path}" \
--endpoint-url "https://${R2_ACCOUNT_ID}.r2.cloudflarestorage.com" \
--content-type "application/vnd.android.package-archive"
echo "${R2_PUBLIC_URL}/${remote_path}"
}
# 清理旧版本 APK只保留最新的 3 个
cleanup_old_apks() {
echo "🧹 清理旧版本 APK..."
# 列出所有 APK 文件,按时间倒序排列
local apk_list=$(AWS_ACCESS_KEY_ID=$R2_ACCESS_KEY_ID \
AWS_SECRET_ACCESS_KEY=$R2_ACCESS_KEY_SECRET \
aws s3 ls "s3://${R2_BUCKET_NAME}/releases/" \
--endpoint-url "https://${R2_ACCOUNT_ID}.r2.cloudflarestorage.com" \
| grep "memory-.*\.apk" \
| sort -r \
| awk '{print $4}')
# 跳过前 3 个(最新的),删除其余的
local count=0
for apk in $apk_list; do
count=$((count + 1))
if [ $count -gt 3 ]; then
echo " 删除: $apk"
AWS_ACCESS_KEY_ID=$R2_ACCESS_KEY_ID \
AWS_SECRET_ACCESS_KEY=$R2_ACCESS_KEY_SECRET \
aws s3 rm "s3://${R2_BUCKET_NAME}/releases/${apk}" \
--endpoint-url "https://${R2_ACCOUNT_ID}.r2.cloudflarestorage.com"
fi
done
if [ $count -le 3 ]; then
echo " 无需清理,当前共 ${count} 个版本"
else
echo "✅ 已清理 $((count - 3)) 个旧版本"
fi
}
# 更新服务器版本信息,返回 0 成功1 失败
update_server_version() {
local version_code=$1
local version_name=$2
local download_url=$3
local update_log=$4
echo "🔄 更新服务器版本信息..."
echo " version_code: ${version_code}"
echo " version_name: ${version_name}"
echo " download_url: ${download_url}"
# 使用 printf 构建正确的 JSON
local json_data=$(printf '{"version_code":%d,"version_name":"%s","download_url":"%s","update_log":"%s","force_update":false}' \
"$version_code" "$version_name" "$download_url" "$update_log")
local response=$(curl -s -w "\n%{http_code}" -X POST "${API_BASE_URL}/version" \
-H "Content-Type: application/json" \
-d "$json_data")
local http_code=$(echo "$response" | tail -n1)
local body=$(echo "$response" | sed '$d')
if [ "$http_code" = "200" ]; then
echo "✅ 服务器版本信息已更新"
return 0
else
echo "❌ 更新服务器版本失败 (HTTP $http_code)"
echo " 响应: $body"
return 1
fi
}
# ============ 主流程 ============
echo "🚀 Memory App 发布脚本"
echo "========================"
# 选择发布内容
echo ""
echo "请选择要发布的内容:"
echo " 1) 只发布 APK"
echo " 2) 只部署后端"
echo " 3) 发布 APK + 部署后端"
echo ""
read -p "请选择 (1/2/3): " choice
BUILD_APK=false
DEPLOY_BACKEND=false
case $choice in
1)
BUILD_APK=true
;;
2)
DEPLOY_BACKEND=true
;;
3)
BUILD_APK=true
DEPLOY_BACKEND=true
;;
*)
echo "❌ 无效选择"
exit 1
;;
esac
# APK 发布流程
if [ "$BUILD_APK" = true ]; then
# 获取当前版本
current_version=$(get_current_version)
current_code=$(get_current_version_code)
echo ""
echo "📌 当前版本: v${current_version} (code: ${current_code})"
# 计算新版本
new_version=$(increment_version $current_version)
new_code=$((current_code + 1))
echo "📌 新版本: v${new_version} (code: ${new_code})"
# 获取更新日志
echo ""
read -p "📝 请输入更新日志: " update_log
if [ -z "$update_log" ]; then
update_log="Bug 修复和性能优化"
fi
echo ""
echo "📋 发布信息:"
echo " 版本: v${new_version} (code: ${new_code})"
echo " 更新日志: ${update_log}"
echo ""
# 更新版本号
echo "📝 更新版本号..."
update_version_in_gradle $new_version $new_code
# 编译
build_apk
# 先更新服务器版本信息,成功后再上传 APK
download_url="${R2_PUBLIC_URL}/releases/memory-${new_version}.apk"
if update_server_version $new_code "$new_version" "$download_url" "$update_log"; then
# 上传 APK
upload_to_r2 $new_version
echo "✅ 上传完成: $download_url"
# 清理旧版本
cleanup_old_apks
echo ""
echo "🎉 APK 发布完成!"
echo " 版本: v${new_version}"
echo " 下载: ${download_url}"
else
echo ""
echo "❌ 服务器版本更新失败APK 未上传"
exit 1
fi
fi
# 后端部署流程
if [ "$DEPLOY_BACKEND" = true ]; then
echo ""
build_docker
deploy_docker
echo ""
echo "🎉 后端部署完成!"
fi
echo ""
echo "✨ 全部完成!"