From aae1b1c45cae2346faa820a371b4047e15510b15 Mon Sep 17 00:00:00 2001 From: edde746 <86283021+edde746@users.noreply.github.com> Date: Wed, 18 Feb 2026 09:14:13 +0100 Subject: [PATCH] refactor: clean up release script and fastlane configs --- android/Gemfile | 10 ++ android/Gemfile.lock | 244 +++++++++++++++++++++++++++++++++++ android/app/build.gradle.kts | 3 + android/fastlane/Fastfile | 44 ++----- android/fastlane/Pluginfile | 5 + ios/fastlane/Fastfile | 31 +---- scripts/release.sh | 140 +++++++------------- scripts/sync_changelogs.sh | 59 --------- 8 files changed, 321 insertions(+), 215 deletions(-) create mode 100644 android/Gemfile create mode 100644 android/Gemfile.lock create mode 100644 android/fastlane/Pluginfile delete mode 100755 scripts/sync_changelogs.sh diff --git a/android/Gemfile b/android/Gemfile new file mode 100644 index 00000000..b734015f --- /dev/null +++ b/android/Gemfile @@ -0,0 +1,10 @@ +# Autogenerated by fastlane +# +# Ensure this file is checked in to source control! + +source "https://rubygems.org" + +gem 'fastlane' + +plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') +eval_gemfile(plugins_path) if File.exist?(plugins_path) diff --git a/android/Gemfile.lock b/android/Gemfile.lock new file mode 100644 index 00000000..f65ada81 --- /dev/null +++ b/android/Gemfile.lock @@ -0,0 +1,244 @@ +GEM + remote: https://rubygems.org/ + specs: + CFPropertyList (3.0.8) + abbrev (0.1.2) + addressable (2.8.8) + public_suffix (>= 2.0.2, < 8.0) + artifactory (3.0.17) + atomos (0.1.3) + aws-eventstream (1.4.0) + aws-partitions (1.1215.0) + aws-sdk-core (3.242.0) + aws-eventstream (~> 1, >= 1.3.0) + aws-partitions (~> 1, >= 1.992.0) + aws-sigv4 (~> 1.9) + base64 + bigdecimal + jmespath (~> 1, >= 1.6.1) + logger + aws-sdk-kms (1.122.0) + aws-sdk-core (~> 3, >= 3.241.4) + aws-sigv4 (~> 1.5) + aws-sdk-s3 (1.213.0) + aws-sdk-core (~> 3, >= 3.241.4) + aws-sdk-kms (~> 1) + aws-sigv4 (~> 1.5) + aws-sigv4 (1.12.1) + aws-eventstream (~> 1, >= 1.0.2) + babosa (1.0.4) + base64 (0.2.0) + benchmark (0.5.0) + bigdecimal (4.0.1) + claide (1.1.0) + colored (1.2) + colored2 (3.1.2) + commander (4.6.0) + highline (~> 2.0.0) + csv (3.3.5) + declarative (0.0.20) + digest-crc (0.7.0) + rake (>= 12.0.0, < 14.0.0) + domain_name (0.6.20240107) + dotenv (2.8.1) + emoji_regex (3.2.3) + excon (0.112.0) + faraday (1.10.5) + faraday-em_http (~> 1.0) + faraday-em_synchrony (~> 1.0) + faraday-excon (~> 1.1) + faraday-httpclient (~> 1.0) + faraday-multipart (~> 1.0) + faraday-net_http (~> 1.0) + faraday-net_http_persistent (~> 1.0) + faraday-patron (~> 1.0) + faraday-rack (~> 1.0) + faraday-retry (~> 1.0) + ruby2_keywords (>= 0.0.4) + faraday-cookie_jar (0.0.8) + faraday (>= 0.8.0) + http-cookie (>= 1.0.0) + faraday-em_http (1.0.0) + faraday-em_synchrony (1.0.1) + faraday-excon (1.1.0) + faraday-httpclient (1.0.1) + faraday-multipart (1.2.0) + multipart-post (~> 2.0) + faraday-net_http (1.0.2) + faraday-net_http_persistent (1.2.0) + faraday-patron (1.0.0) + faraday-rack (1.0.0) + faraday-retry (1.0.3) + faraday_middleware (1.2.1) + faraday (~> 1.0) + fastimage (2.4.0) + fastlane (2.232.1) + CFPropertyList (>= 2.3, < 4.0.0) + abbrev (~> 0.1.2) + addressable (>= 2.8, < 3.0.0) + artifactory (~> 3.0) + aws-sdk-s3 (~> 1.197) + babosa (>= 1.0.3, < 2.0.0) + base64 (~> 0.2.0) + benchmark (>= 0.1.0) + bundler (>= 1.17.3, < 5.0.0) + colored (~> 1.2) + commander (~> 4.6) + csv (~> 3.3) + dotenv (>= 2.1.1, < 3.0.0) + emoji_regex (>= 0.1, < 4.0) + excon (>= 0.71.0, < 1.0.0) + faraday (~> 1.0) + faraday-cookie_jar (~> 0.0.6) + faraday_middleware (~> 1.0) + fastimage (>= 2.1.0, < 3.0.0) + fastlane-sirp (>= 1.0.0) + gh_inspector (>= 1.1.2, < 2.0.0) + google-apis-androidpublisher_v3 (~> 0.3) + google-apis-playcustomapp_v1 (~> 0.1) + google-cloud-env (>= 1.6.0, <= 2.1.1) + google-cloud-storage (~> 1.31) + highline (~> 2.0) + http-cookie (~> 1.0.5) + json (< 3.0.0) + jwt (>= 2.1.0, < 3) + logger (>= 1.6, < 2.0) + mini_magick (>= 4.9.4, < 5.0.0) + multipart-post (>= 2.0.0, < 3.0.0) + mutex_m (~> 0.3.0) + naturally (~> 2.2) + nkf (~> 0.2.0) + optparse (>= 0.1.1, < 1.0.0) + ostruct (>= 0.1.0) + plist (>= 3.1.0, < 4.0.0) + rubyzip (>= 2.0.0, < 3.0.0) + security (= 0.1.5) + simctl (~> 1.6.3) + terminal-notifier (>= 2.0.0, < 3.0.0) + terminal-table (~> 3) + tty-screen (>= 0.6.3, < 1.0.0) + tty-spinner (>= 0.8.0, < 1.0.0) + word_wrap (~> 1.0.0) + xcodeproj (>= 1.13.0, < 2.0.0) + xcpretty (~> 0.4.1) + xcpretty-travis-formatter (>= 0.0.3, < 2.0.0) + fastlane-plugin-amazon_appstore (1.4.0) + faraday (~> 1.0) + faraday_middleware (~> 1.0) + fastlane-sirp (1.0.0) + sysrandom (~> 1.0) + gh_inspector (1.1.3) + google-apis-androidpublisher_v3 (0.96.0) + google-apis-core (>= 0.15.0, < 2.a) + google-apis-core (0.18.0) + addressable (~> 2.5, >= 2.5.1) + googleauth (~> 1.9) + httpclient (>= 2.8.3, < 3.a) + mini_mime (~> 1.0) + mutex_m + representable (~> 3.0) + retriable (>= 2.0, < 4.a) + google-apis-iamcredentials_v1 (0.26.0) + google-apis-core (>= 0.15.0, < 2.a) + google-apis-playcustomapp_v1 (0.17.0) + google-apis-core (>= 0.15.0, < 2.a) + google-apis-storage_v1 (0.60.0) + google-apis-core (>= 0.15.0, < 2.a) + google-cloud-core (1.8.0) + google-cloud-env (>= 1.0, < 3.a) + google-cloud-errors (~> 1.0) + google-cloud-env (2.1.1) + faraday (>= 1.0, < 3.a) + google-cloud-errors (1.5.0) + google-cloud-storage (1.58.0) + addressable (~> 2.8) + digest-crc (~> 0.4) + google-apis-core (>= 0.18, < 2) + google-apis-iamcredentials_v1 (~> 0.18) + google-apis-storage_v1 (>= 0.42) + google-cloud-core (~> 1.6) + googleauth (~> 1.9) + mini_mime (~> 1.0) + googleauth (1.11.2) + faraday (>= 1.0, < 3.a) + google-cloud-env (~> 2.1) + jwt (>= 1.4, < 3.0) + multi_json (~> 1.11) + os (>= 0.9, < 2.0) + signet (>= 0.16, < 2.a) + highline (2.0.3) + http-cookie (1.0.8) + domain_name (~> 0.5) + httpclient (2.9.0) + mutex_m + jmespath (1.6.2) + json (2.18.1) + jwt (2.10.2) + base64 + logger (1.7.0) + mini_magick (4.13.2) + mini_mime (1.1.5) + multi_json (1.19.1) + multipart-post (2.4.1) + mutex_m (0.3.0) + nanaimo (0.4.0) + naturally (2.3.0) + nkf (0.2.0) + optparse (0.8.1) + os (1.1.4) + ostruct (0.6.3) + plist (3.7.2) + public_suffix (7.0.2) + rake (13.3.1) + representable (3.2.0) + declarative (< 0.1.0) + trailblazer-option (>= 0.1.1, < 0.2.0) + uber (< 0.2.0) + retriable (3.1.2) + rexml (3.4.4) + rouge (3.28.0) + ruby2_keywords (0.0.5) + rubyzip (2.4.1) + security (0.1.5) + signet (0.21.0) + addressable (~> 2.8) + faraday (>= 0.17.5, < 3.a) + jwt (>= 1.5, < 4.0) + multi_json (~> 1.10) + simctl (1.6.10) + CFPropertyList + naturally + sysrandom (1.0.5) + terminal-notifier (2.0.0) + terminal-table (3.0.2) + unicode-display_width (>= 1.1.1, < 3) + trailblazer-option (0.1.2) + tty-cursor (0.7.1) + tty-screen (0.8.2) + tty-spinner (0.9.3) + tty-cursor (~> 0.7) + uber (0.1.0) + unicode-display_width (2.6.0) + word_wrap (1.0.0) + xcodeproj (1.27.0) + CFPropertyList (>= 2.3.3, < 4.0) + atomos (~> 0.1.3) + claide (>= 1.0.2, < 2.0) + colored2 (~> 3.1) + nanaimo (~> 0.4.0) + rexml (>= 3.3.6, < 4.0) + xcpretty (0.4.1) + rouge (~> 3.28.0) + xcpretty-travis-formatter (1.0.1) + xcpretty (~> 0.2, >= 0.0.7) + +PLATFORMS + arm64-darwin-25 + ruby + +DEPENDENCIES + fastlane + fastlane-plugin-amazon_appstore + +BUNDLED WITH + 2.7.2 diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index ae999a44..b449dcac 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -55,6 +55,9 @@ android { signingConfig = signingConfigs.getByName("release") } // If key.properties doesn't exist, it will use debug signing for CI builds + ndk { + debugSymbolLevel = "FULL" + } } } diff --git a/android/fastlane/Fastfile b/android/fastlane/Fastfile index 35024f0b..0edccf7a 100644 --- a/android/fastlane/Fastfile +++ b/android/fastlane/Fastfile @@ -4,37 +4,6 @@ Dotenv.load("../../.env") default_platform(:android) platform :android do - desc "Deploy a new version to the Google Play" - lane :deploy do - gradle(task: "clean bundleRelease") - - # Get version code from pubspec.yaml - pubspec_path = "#{ENV['PWD']}/../pubspec.yaml" - pubspec_content = File.read(pubspec_path) - version_match = pubspec_content.match(/version:\s*(.+)\+(\d+)/) - - if version_match - version_code = version_match[2].to_i - UI.message("Using version code: #{version_code}") - else - UI.user_error!("Could not extract version code from pubspec.yaml") - end - - upload_to_play_store( - version_code: version_code, - skip_upload_changelogs: true, - skip_upload_metadata: true, - skip_upload_images: true, - skip_upload_screenshots: true - ) - end - - desc "Build release AAB" - lane :build do - # Navigate to Flutter project root and build - sh("cd #{ENV['PWD']}/.. && flutter build appbundle --dart-define=ENABLE_IN_APP_REVIEW=true") - end - desc "Build and deploy to Google Play Store" lane :release do # Build the Flutter app @@ -52,12 +21,17 @@ platform :android do UI.user_error!("Could not extract version code from pubspec.yaml") end - # Upload to Play Store upload_to_play_store( - track: "internal", - release_status: "draft", + track: "production", + release_status: "completed", version_code: version_code, aab: "../build/app/outputs/bundle/release/app-release.aab" ) + + upload_to_amazon_appstore( + apk: "../build/app/outputs/bundle/release/app-release.aab", + overwrite_upload: true, + overwrite_upload_mode: 'reuse' + ) end -end \ No newline at end of file +end diff --git a/android/fastlane/Pluginfile b/android/fastlane/Pluginfile new file mode 100644 index 00000000..78bba913 --- /dev/null +++ b/android/fastlane/Pluginfile @@ -0,0 +1,5 @@ +# Autogenerated by fastlane +# +# Ensure this file is checked in to source control! + +gem 'fastlane-plugin-amazon_appstore' diff --git a/ios/fastlane/Fastfile b/ios/fastlane/Fastfile index 379fab29..e766bbff 100644 --- a/ios/fastlane/Fastfile +++ b/ios/fastlane/Fastfile @@ -4,35 +4,6 @@ Dotenv.load("../../.env") default_platform(:ios) platform :ios do - desc "Push a new beta build to TestFlight" - lane :beta do - build_app(workspace: "Runner.xcworkspace", scheme: "Runner") - upload_to_testflight - end - - desc "Push a new release build to the App Store" - lane :release do - build_app(workspace: "Runner.xcworkspace", scheme: "Runner") - upload_to_app_store - end - - desc "Build release IPA" - lane :build do - # Navigate to Flutter project root and build - sh("cd #{ENV['PWD']}/.. && flutter build ipa --dart-define=ENABLE_IN_APP_REVIEW=true") - end - - desc "Build and deploy to TestFlight" - lane :deploy_testflight do - # Build the Flutter app - sh("cd #{ENV['PWD']}/.. && flutter build ipa --dart-define=ENABLE_IN_APP_REVIEW=true") - - # Upload to TestFlight - upload_to_testflight( - skip_waiting_for_build_processing: true - ) - end - desc "Build and deploy to App Store" lane :deploy_appstore do # Build the Flutter app @@ -46,4 +17,4 @@ platform :ios do skip_screenshots: true, # https://github.com/fastlane/fastlane/issues/29735 ) end -end \ No newline at end of file +end diff --git a/scripts/release.sh b/scripts/release.sh index a271fb9d..7060c120 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -1,135 +1,93 @@ #!/bin/bash -# Plezy Release Automation Script -# This script automates the release process for both iOS and Android - set -e -# Get the script's directory -SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$SCRIPT_DIR/.." -# Colors for output -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -RED='\033[0;31m' -NC='\033[0m' # No Color - -# Load environment variables from .env if [ -f "$PROJECT_ROOT/.env" ]; then - # Export variables without executing the file set -a source "$PROJECT_ROOT/.env" set +a - echo -e "${GREEN}โœ… Loaded environment variables from .env${NC}" else - echo -e "${RED}โŒ Error: .env file not found${NC}" + echo "Error: .env file not found" exit 1 fi -# Function to show help -show_help() { - echo -e "${BLUE}Plezy Release Automation${NC}" +create_changelogs() { + local notes_file="$1" + if [ -z "$notes_file" ] || [ ! -f "$notes_file" ]; then + echo "Usage: release.sh changelog " + exit 1 + fi + + local version_code + version_code=$(grep -E 'version:' "$PROJECT_ROOT/pubspec.yaml" | sed -E 's/.*\+([0-9]+).*/\1/') + + local prompt="Below is a changelog for a cross-platform Flutter app (iOS, Android, macOS, Linux, Windows). Return ONLY the entries relevant to the given platform. Keep the same format (section headers + bullet points). If a section has no relevant entries, omit it entirely. If an entry is not platform-specific, include it. You MUST stay under the character limit. Aggressively drop less important entries and consolidate similar ones to fit. Count your output characters before responding. Output nothing else." + local notes + notes=$(cat "$notes_file") + + local ios_notes android_notes + ios_notes=$(echo "$notes" | claude --print "$prompt Platform: iOS. Max 4000 characters.") + android_notes=$(echo "$notes" | claude --print "$prompt Platform: Android. Max 500 characters.") + + local ios_path="$PROJECT_ROOT/ios/fastlane/metadata/en-US/release_notes.txt" + local android_path="$PROJECT_ROOT/android/fastlane/metadata/android/en-GB/changelogs/${version_code}.txt" + + mkdir -p "$(dirname "$ios_path")" "$(dirname "$android_path")" + echo "$ios_notes" > "$ios_path" + echo "$android_notes" > "$android_path" + + local ios_len=${#ios_notes} + local android_len=${#android_notes} + + echo "iOS changelog (${ios_len}/4000 chars):" + echo "$ios_notes" echo "" - echo "Usage: ./scripts/release.sh " - echo "" - echo "Available commands:" - echo " sync - Sync iOS release notes to Android changelog" - echo " android - Build and release to Google Play Store" - echo " ios - Build and release to App Store" - echo " all - Sync changelogs and release to both platforms" - echo " clean - Clean build artifacts" - echo " help - Show this help message" - echo "" - echo "Prerequisites:" - echo " - .env file must be configured with credentials" - echo " - iOS release notes updated in ios/fastlane/metadata/en-US/release_notes.txt" - echo " - Version bumped in pubspec.yaml" - echo "" - echo "Example:" - echo " ./scripts/release.sh all" + echo "Android changelog ${version_code}.txt (${android_len}/500 chars):" + echo "$android_notes" } -# Function to sync changelogs -sync_changelogs() { - echo -e "${YELLOW}๐Ÿ“ Syncing changelogs...${NC}" - "$SCRIPT_DIR/sync_changelogs.sh" -} - -# Function to release Android release_android() { - echo -e "${GREEN}๐Ÿค– Building and releasing Android app...${NC}" cd "$PROJECT_ROOT/android" fastlane release cd "$PROJECT_ROOT" } -# Function to release iOS release_ios() { - echo -e "${GREEN}๐ŸŽ Building and releasing iOS app...${NC}" cd "$PROJECT_ROOT/ios" fastlane deploy_appstore cd "$PROJECT_ROOT" } -# Function to release all -release_all() { - sync_changelogs - echo "" - release_android - echo "" - release_ios - echo "" - echo -e "${GREEN}โœ… Release complete for both platforms!${NC}" - echo "" - echo -e "${YELLOW}Next steps:${NC}" - echo " 1. Check Google Play Console for the draft release" - echo " 2. Check App Store Connect for the uploaded build" - echo " 3. Submit for review when ready" -} - -# Function to clean build artifacts clean() { - echo -e "${YELLOW}๐Ÿงน Cleaning build artifacts...${NC}" cd "$PROJECT_ROOT/android" ./gradlew clean 2>/dev/null || true cd "$PROJECT_ROOT/ios" xcodebuild clean -workspace Runner.xcworkspace -scheme Runner 2>/dev/null || true cd "$PROJECT_ROOT" flutter clean - echo -e "${GREEN}โœ… Clean complete!${NC}" } -# Main script logic -if [ $# -eq 0 ]; then - show_help - exit 0 -fi - -case "$1" in - sync) - sync_changelogs - ;; - android) - release_android - ;; - ios) - release_ios - ;; - all) - release_all - ;; - clean) - clean - ;; +case "${1:-help}" in + changelog) create_changelogs "$2" ;; + android) release_android ;; + ios) release_ios ;; + all) release_android && release_ios ;; + clean) clean ;; help|--help|-h) - show_help + echo "Usage: ./scripts/release.sh " + echo "" + echo "Commands:" + echo " changelog Generate platform-specific changelogs from a notes file" + echo " android Build and release to Google Play Store" + echo " ios Build and release to App Store" + echo " all Release to both platforms" + echo " clean Clean build artifacts" ;; *) - echo -e "${RED}โŒ Unknown command: $1${NC}" - echo "" - show_help + echo "Unknown command: $1" exit 1 ;; esac diff --git a/scripts/sync_changelogs.sh b/scripts/sync_changelogs.sh deleted file mode 100755 index 9c1a31b7..00000000 --- a/scripts/sync_changelogs.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/bash - -# Sync changelogs between iOS and Android -# This script copies the iOS release notes to the Android changelog for the current version - -set -e - -# Get the script's directory -SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -PROJECT_ROOT="$SCRIPT_DIR/.." - -# Colors for output -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -RED='\033[0;31m' -NC='\033[0m' # No Color - -echo -e "${GREEN}๐Ÿ“ Syncing changelogs between iOS and Android${NC}" - -# Extract version code from pubspec.yaml -PUBSPEC_PATH="$PROJECT_ROOT/pubspec.yaml" -if [ ! -f "$PUBSPEC_PATH" ]; then - echo -e "${RED}Error: pubspec.yaml not found at $PUBSPEC_PATH${NC}" - exit 1 -fi - -VERSION_CODE=$(grep -E "version:\s*(.+)\+(\d+)" "$PUBSPEC_PATH" | sed -E 's/.*\+([0-9]+).*/\1/') - -if [ -z "$VERSION_CODE" ]; then - echo -e "${RED}Error: Could not extract version code from pubspec.yaml${NC}" - exit 1 -fi - -echo -e "${YELLOW}Current version code: $VERSION_CODE${NC}" - -# Define paths -IOS_RELEASE_NOTES="$PROJECT_ROOT/ios/fastlane/metadata/en-US/release_notes.txt" -ANDROID_CHANGELOG="$PROJECT_ROOT/android/fastlane/metadata/android/en-GB/changelogs/$VERSION_CODE.txt" - -# Check if iOS release notes exist -if [ ! -f "$IOS_RELEASE_NOTES" ]; then - echo -e "${RED}Error: iOS release notes not found at $IOS_RELEASE_NOTES${NC}" - exit 1 -fi - -# Create Android changelogs directory if it doesn't exist -ANDROID_CHANGELOGS_DIR="$(dirname "$ANDROID_CHANGELOG")" -mkdir -p "$ANDROID_CHANGELOGS_DIR" - -# Copy iOS release notes to Android changelog -cp "$IOS_RELEASE_NOTES" "$ANDROID_CHANGELOG" - -echo -e "${GREEN}โœ… Successfully synced changelog!${NC}" -echo -e " iOS release notes โ†’ Android changelog ($VERSION_CODE.txt)" -echo "" -echo -e "${YELLOW}Next steps:${NC}" -echo "1. Review the changelog at: $ANDROID_CHANGELOG" -echo "2. Commit the changes" -echo "3. Run fastlane to deploy"