Files
healthflow/release.sh
2026-01-02 17:35:32 +08:00

312 lines
8.9 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
# HealthFlow 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="http://95.181.190.226:6601/api"
# 服务器配置
SERVER_HOST="95.181.190.226"
SERVER_PORT="33"
SERVER_USER="root"
SERVER_PASSWORD="xiaobiao."
SERVER_PROJECT_PATH="/amos/healthFlow"
# 签名配置
KEYSTORE_FILE="release.keystore"
KEYSTORE_PASSWORD="healthflow123"
KEY_ALIAS="healthflow"
KEY_PASSWORD="healthflow123"
# ============ 函数定义 ============
# 获取当前版本号
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 healthflow-server:latest .
docker save healthflow-server:latest -o healthflow-server.tar
cd ..
echo "✅ Docker 镜像已导出到 server/healthflow-server.tar"
}
# 部署 Docker 镜像到服务器
deploy_docker() {
echo "🚀 部署 Docker 镜像到服务器..."
# 上传镜像到服务器
echo "📤 上传镜像文件..."
sshpass -p "${SERVER_PASSWORD}" scp -P ${SERVER_PORT} -o StrictHostKeyChecking=no server/healthflow-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 healthflow-server.tar
docker compose down
docker compose up -d
# 清理旧镜像
echo "🧹 清理旧镜像..."
docker image prune -f
# 删除镜像文件
rm -f healthflow-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="healthFlow/releases/healthflow-${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}/healthFlow/releases/" \
--endpoint-url "https://${R2_ACCOUNT_ID}.r2.cloudflarestorage.com" \
| grep "\.apk$" \
| sort -k1,2 \
| awk '{print $4}')
# 计算 APK 数量
local count=$(echo "$apk_list" | grep -c "\.apk$" || echo "0")
if [ "$count" -gt 3 ]; then
# 需要删除的数量
local to_delete=$((count - 3))
echo " 发现 ${count} 个 APK将删除最旧的 ${to_delete}"
# 获取要删除的文件列表(最旧的几个)
local files_to_delete=$(echo "$apk_list" | head -n $to_delete)
for file in $files_to_delete; do
echo " 删除: ${file}"
AWS_ACCESS_KEY_ID=$R2_ACCESS_KEY_ID \
AWS_SECRET_ACCESS_KEY=$R2_ACCESS_KEY_SECRET \
aws s3 rm "s3://${R2_BUCKET_NAME}/healthFlow/releases/${file}" \
--endpoint-url "https://${R2_ACCOUNT_ID}.r2.cloudflarestorage.com"
done
echo "✅ 清理完成,保留最近 3 个版本"
else
echo " 当前只有 ${count} 个 APK无需清理"
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 "🚀 HealthFlow 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}/healthFlow/releases/healthflow-${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"
# 清理旧 APK
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 ""
echo "🐳 开始部署后端..."
build_docker
deploy_docker
echo ""
echo "🎉 后端部署完成!"
fi
echo ""
echo "✨ 全部完成!"