diff --git a/frontend/mining-app/.gitignore b/frontend/mining-app/.gitignore index 3820a95c..ad1c274d 100644 --- a/frontend/mining-app/.gitignore +++ b/frontend/mining-app/.gitignore @@ -43,3 +43,9 @@ app.*.map.json /android/app/debug /android/app/profile /android/app/release + +# Auto-generated version code (each dev machine maintains its own) +/android/app/version.properties + +# Build publish output +/publish/ diff --git a/frontend/mining-app/android/app/build.gradle.kts b/frontend/mining-app/android/app/build.gradle.kts index 49621656..b18e71af 100644 --- a/frontend/mining-app/android/app/build.gradle.kts +++ b/frontend/mining-app/android/app/build.gradle.kts @@ -1,3 +1,7 @@ +import java.util.Properties +import java.io.FileInputStream +import java.io.FileOutputStream + plugins { id("com.android.application") id("kotlin-android") @@ -5,6 +9,33 @@ plugins { id("dev.flutter.flutter-gradle-plugin") } +// ============================================ +// Auto-increment version code on each build +// ============================================ +val versionPropertiesFile = rootProject.file("app/version.properties") +val versionProperties = Properties() + +fun calculateNextVersionCode(): Int { + if (versionPropertiesFile.exists()) { + versionProperties.load(FileInputStream(versionPropertiesFile)) + } + val currentCode = versionProperties.getProperty("VERSION_CODE", "0").toInt() + val newCode = currentCode + 1 + versionProperties.setProperty("VERSION_CODE", newCode.toString()) + versionProperties.store(FileOutputStream(versionPropertiesFile), "Auto-generated version code - DO NOT EDIT MANUALLY") + return newCode +} + +// Get auto-incremented version code +val autoVersionCode = calculateNextVersionCode() + +// Version name format: major.minor.patch (from pubspec.yaml) + build number +// Example: 1.0.0.123 +fun getAutoVersionName(): String { + val flutterVersionName = flutter.versionName + return "$flutterVersionName.$autoVersionCode" +} + android { namespace = "com.rwadurian.mining_app" compileSdk = flutter.compileSdkVersion @@ -23,8 +54,9 @@ android { applicationId = "com.rwadurian.mining_app" minSdk = 24 targetSdk = flutter.targetSdkVersion - versionCode = flutter.versionCode - versionName = flutter.versionName + // Auto-incremented version code and name + versionCode = autoVersionCode + versionName = getAutoVersionName() // 多dex支持 multiDexEnabled = true diff --git a/frontend/mining-app/scripts/build.sh b/frontend/mining-app/scripts/build.sh new file mode 100644 index 00000000..ddd58619 --- /dev/null +++ b/frontend/mining-app/scripts/build.sh @@ -0,0 +1,130 @@ +#!/bin/bash +# ============================================================================= +# Flutter APK 构建脚本(自动增加构建号) +# ============================================================================= +# 用法: +# ./scripts/build.sh # 构建 release APK,自动增加构建号 +# ./scripts/build.sh --no-bump # 构建但不增加构建号 +# ./scripts/build.sh --set 100 # 设置指定构建号 +# ============================================================================= + +set -e + +# 颜色 +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } +log_success() { echo -e "${GREEN}[OK]${NC} $1"; } +log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } + +# 获取脚本目录 +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_DIR="$(dirname "$SCRIPT_DIR")" +PUBSPEC_FILE="$PROJECT_DIR/pubspec.yaml" + +# 读取当前版本 +get_current_version() { + grep "^version:" "$PUBSPEC_FILE" | sed 's/version: //' +} + +# 解析版本号 +parse_version() { + local version="$1" + VERSION_NAME=$(echo "$version" | cut -d'+' -f1) + BUILD_NUMBER=$(echo "$version" | cut -d'+' -f2) +} + +# 更新版本号 +update_version() { + local new_version="$1" + if [[ "$OSTYPE" == "darwin"* ]]; then + # macOS + sed -i '' "s/^version:.*/version: $new_version/" "$PUBSPEC_FILE" + else + # Linux + sed -i "s/^version:.*/version: $new_version/" "$PUBSPEC_FILE" + fi +} + +# 主函数 +main() { + cd "$PROJECT_DIR" + + # 获取当前版本 + CURRENT_VERSION=$(get_current_version) + parse_version "$CURRENT_VERSION" + + log_info "当前版本: $CURRENT_VERSION" + log_info "版本名: $VERSION_NAME, 构建号: $BUILD_NUMBER" + + # 处理参数 + BUMP_VERSION=true + NEW_BUILD_NUMBER="" + + while [[ $# -gt 0 ]]; do + case $1 in + --no-bump) + BUMP_VERSION=false + shift + ;; + --set) + NEW_BUILD_NUMBER="$2" + shift 2 + ;; + *) + shift + ;; + esac + done + + # 更新构建号 + if [ -n "$NEW_BUILD_NUMBER" ]; then + BUILD_NUMBER="$NEW_BUILD_NUMBER" + log_info "设置构建号为: $BUILD_NUMBER" + elif [ "$BUMP_VERSION" = true ]; then + BUILD_NUMBER=$((BUILD_NUMBER + 1)) + log_info "自动增加构建号为: $BUILD_NUMBER" + fi + + NEW_VERSION="${VERSION_NAME}+${BUILD_NUMBER}" + + if [ "$CURRENT_VERSION" != "$NEW_VERSION" ]; then + update_version "$NEW_VERSION" + log_success "版本更新为: $NEW_VERSION" + fi + + # 清理并获取依赖 + log_info "获取依赖..." + flutter pub get + + # 构建 APK + log_info "构建 Release APK..." + flutter build apk --release + + # 输出结果 + APK_PATH="$PROJECT_DIR/build/app/outputs/flutter-apk/app-release.apk" + if [ -f "$APK_PATH" ]; then + APK_SIZE=$(du -h "$APK_PATH" | cut -f1) + log_success "构建完成!" + echo "" + echo "APK 信息:" + echo " 版本: $NEW_VERSION" + echo " 路径: $APK_PATH" + echo " 大小: $APK_SIZE" + echo "" + + # 复制到 publish 目录 + PUBLISH_DIR="$PROJECT_DIR/publish" + mkdir -p "$PUBLISH_DIR" + cp "$APK_PATH" "$PUBLISH_DIR/mining-app-${VERSION_NAME}-${BUILD_NUMBER}.apk" + log_success "已复制到: $PUBLISH_DIR/mining-app-${VERSION_NAME}-${BUILD_NUMBER}.apk" + else + log_warn "APK 文件未找到" + exit 1 + fi +} + +main "$@"