diff --git a/app/Gemfile b/app/Gemfile index b5b13667f0..7e41c8b9c1 100644 --- a/app/Gemfile +++ b/app/Gemfile @@ -8,7 +8,7 @@ gem "cocoapods", ">= 1.13", "!= 1.15.0", "!= 1.15.1" gem "activesupport", ">= 6.1.7.5", "!= 7.1.0" # Add fastlane for CI/CD -gem "fastlane", "~> 2.228.0" +gem "fastlane", "~> 2.230.0" group :development do gem "dotenv" diff --git a/app/Gemfile.lock b/app/Gemfile.lock index ef2feddd21..39d601d6f8 100644 --- a/app/Gemfile.lock +++ b/app/Gemfile.lock @@ -2,6 +2,7 @@ GEM remote: https://rubygems.org/ specs: CFPropertyList (3.0.8) + abbrev (0.1.2) activesupport (7.2.3) base64 benchmark (>= 0.3) @@ -22,8 +23,8 @@ GEM artifactory (3.0.17) atomos (0.1.3) aws-eventstream (1.4.0) - aws-partitions (1.1198.0) - aws-sdk-core (3.240.0) + aws-partitions (1.1200.0) + aws-sdk-core (3.241.1) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.992.0) aws-sigv4 (~> 1.9) @@ -31,17 +32,17 @@ GEM bigdecimal jmespath (~> 1, >= 1.6.1) logger - aws-sdk-kms (1.118.0) - aws-sdk-core (~> 3, >= 3.239.1) + aws-sdk-kms (1.119.0) + aws-sdk-core (~> 3, >= 3.241.0) aws-sigv4 (~> 1.5) - aws-sdk-s3 (1.209.0) - aws-sdk-core (~> 3, >= 3.234.0) + aws-sdk-s3 (1.210.1) + aws-sdk-core (~> 3, >= 3.241.0) 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.3.0) + base64 (0.2.0) benchmark (0.5.0) bigdecimal (4.0.1) claide (1.1.0) @@ -88,6 +89,7 @@ GEM highline (~> 2.0.0) concurrent-ruby (1.3.6) connection_pool (3.0.2) + csv (3.3.5) declarative (0.0.20) digest-crc (0.7.0) rake (>= 12.0.0, < 14.0.0) @@ -128,15 +130,18 @@ GEM faraday_middleware (1.2.1) faraday (~> 1.0) fastimage (2.4.0) - fastlane (2.228.0) + fastlane (2.230.0) CFPropertyList (>= 2.3, < 4.0.0) + abbrev (~> 0.1.2) addressable (>= 2.8, < 3.0.0) artifactory (~> 3.0) aws-sdk-s3 (~> 1.0) babosa (>= 1.0.3, < 2.0.0) + base64 (~> 0.2.0) bundler (>= 1.12.0, < 3.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) @@ -154,9 +159,12 @@ GEM 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) plist (>= 3.1.0, < 4.0.0) rubyzip (>= 2.0.0, < 3.0.0) @@ -232,13 +240,14 @@ GEM minitest (6.0.0) prism (~> 1.5) molinillo (0.8.0) - multi_json (1.18.0) + multi_json (1.19.1) multipart-post (2.4.1) mutex_m (0.3.0) nanaimo (0.4.0) nap (1.1.0) naturally (2.3.0) netrc (0.11.0) + nkf (0.2.0) nokogiri (1.18.10) mini_portile2 (~> 2.8.2) racc (~> 1.4) @@ -304,7 +313,7 @@ DEPENDENCIES activesupport (>= 6.1.7.5, != 7.1.0) cocoapods (>= 1.13, != 1.15.1, != 1.15.0) dotenv - fastlane (~> 2.228.0) + fastlane (~> 2.230.0) fastlane-plugin-increment_version_code fastlane-plugin-versioning_android nokogiri (~> 1.18) diff --git a/app/fastlane/Fastfile b/app/fastlane/Fastfile index 3101b9ee43..a0d0913e03 100644 --- a/app/fastlane/Fastfile +++ b/app/fastlane/Fastfile @@ -172,6 +172,10 @@ platform :ios do Fastlane::Helpers.verify_env_vars(required_env_vars) + if local_development && version_bump != "skip" + Fastlane::Helpers.bump_local_build_number("ios") + end + # Read build number from version.json (already set by CI or local version-manager.cjs) build_number = Fastlane::Helpers.get_ios_build_number UI.message("๐Ÿ“ฆ Using iOS build number: #{build_number}") @@ -310,18 +314,14 @@ platform :android do # Uploads must be done by CI/CD machines with proper authentication if local_development && !skip_upload skip_upload = true - UI.important("๐Ÿ  LOCAL DEVELOPMENT: Automatically skipping Play Store upload") - UI.important(" Uploads require CI/CD machine permissions and will be handled automatically") + UI.important("๐Ÿ  LOCAL DEVELOPMENT: Play Store uploads are disabled") + UI.important(" Upload the AAB manually in the Play Console after the build finishes") end if local_development if ENV["ANDROID_KEYSTORE_PATH"].nil? ENV["ANDROID_KEYSTORE_PATH"] = Fastlane::Helpers.android_create_keystore(android_keystore_path) end - - if ENV["ANDROID_PLAY_STORE_JSON_KEY_PATH"].nil? - ENV["ANDROID_PLAY_STORE_JSON_KEY_PATH"] = Fastlane::Helpers.android_create_play_store_key(android_play_store_json_key_path) - end end required_env_vars = [ @@ -332,11 +332,13 @@ platform :android do "ANDROID_KEY_PASSWORD", "ANDROID_PACKAGE_NAME", ] - # Only require JSON key path when not running in CI (local development) - required_env_vars << "ANDROID_PLAY_STORE_JSON_KEY_PATH" if local_development Fastlane::Helpers.verify_env_vars(required_env_vars) + if local_development && version_bump != "skip" + Fastlane::Helpers.bump_local_build_number("android") + end + # Read version code from version.json (already set by CI or local version-manager.cjs) version_code = Fastlane::Helpers.get_android_build_number UI.message("๐Ÿ“ฆ Using Android build number: #{version_code}") @@ -353,13 +355,6 @@ platform :android do target_platform = options[:track] == "production" ? "Google Play" : "Internal Testing" should_upload = Fastlane::Helpers.should_upload_app(target_platform) - # Validate JSON key only in local development; CI uses Workload Identity Federation (ADC) - if local_development - validate_play_store_json_key( - json_key: ENV["ANDROID_PLAY_STORE_JSON_KEY_PATH"], - ) - end - Fastlane::Helpers.with_retry(max_retries: 3, delay: 10) do gradle( task: "clean bundleRelease --stacktrace --info", @@ -376,6 +371,9 @@ platform :android do if test_mode || skip_upload if skip_upload UI.important("๐Ÿ”จ BUILD ONLY: Skipping Play Store upload") + if local_development + UI.important("๐Ÿ“ฆ Manual upload required: #{android_aab_path}") + end else UI.important("๐Ÿงช TEST MODE: Skipping Play Store upload") end diff --git a/app/fastlane/helpers/version_manager.rb b/app/fastlane/helpers/version_manager.rb index 3bb97a6cb1..3526516115 100644 --- a/app/fastlane/helpers/version_manager.rb +++ b/app/fastlane/helpers/version_manager.rb @@ -44,6 +44,20 @@ def get_android_build_number data["android"]["build"] end + def bump_local_build_number(platform) + unless %w[ios android].include?(platform) + UI.user_error!("Invalid platform: #{platform}. Must be 'ios' or 'android'") + end + + data = read_version_file + data[platform]["build"] += 1 + + write_version_file(data) + UI.success("Bumped #{platform} build number to #{data[platform]["build"]}") + + data[platform]["build"] + end + def verify_ci_version_match # Verify that versions were pre-set by CI unless ENV["CI_VERSION"] && ENV["CI_IOS_BUILD"] && ENV["CI_ANDROID_BUILD"] diff --git a/app/scripts/mobile-deploy-confirm.cjs b/app/scripts/mobile-deploy-confirm.cjs index fe9bccf519..90edc45e27 100755 --- a/app/scripts/mobile-deploy-confirm.cjs +++ b/app/scripts/mobile-deploy-confirm.cjs @@ -441,6 +441,14 @@ function displayWarningsAndGitStatus() { function displayFullConfirmation(platform, versions, deploymentMethod) { displayDeploymentHeader(platform); displayDeploymentMethod(deploymentMethod); + if ( + deploymentMethod === DEPLOYMENT_METHODS.LOCAL_FASTLANE && + (platform === PLATFORMS.ANDROID || platform === PLATFORMS.BOTH) + ) { + console.log( + `${CONSOLE_SYMBOLS.WARNING} Local Android uploads are disabled. You'll need to manually upload the AAB in Play Console.`, + ); + } displayPlatformVersions(platform, versions); displayWarningsAndGitStatus(); }