From 110a9d75de3bb746954f5053b6eb7a5c9a587b27 Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Sat, 26 Jul 2025 02:39:14 +0200 Subject: [PATCH 01/22] Add methods to manage versioning --- fastlane/Fastfile | 77 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 73507392..6703132e 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -7,6 +7,15 @@ UI.user_error!('Please run fastlane via `bundle exec`') unless FastlaneCore::Hel ######################################################################## # Constants ######################################################################## +PROJECT_ROOT_FOLDER = File.dirname(File.expand_path(__dir__)) + +VERSION_PROPERTIES_PATH = File.join(PROJECT_ROOT_FOLDER, 'version.properties') +VERSION_FILE = Fastlane::Wpmreleasetoolkit::Versioning::AndroidVersionFile.new(version_properties_path: VERSION_PROPERTIES_PATH) + +VERSION_CALCULATOR = Fastlane::Wpmreleasetoolkit::Versioning::SemanticVersionCalculator.new +VERSION_FORMATTER = Fastlane::Wpmreleasetoolkit::Versioning::RCNotationVersionFormatter.new +BUILD_CODE_CALCULATOR = Fastlane::Wpmreleasetoolkit::Versioning::SimpleBuildCodeCalculator.new +BUILD_CODE_FORMATTER = Fastlane::Wpmreleasetoolkit::Versioning::SimpleBuildCodeFormatter.new PROTOTYPE_BUILD_DOMAIN = 'https://cdn.a8c-ci.services' PROTOTYPE_BUILD_TYPE = 'release' @@ -76,4 +85,72 @@ platform :android do "#{branch}-#{commit}" end end + + ##################################################################################### + # Version Methods + ##################################################################################### + + # Updates the build code in version.properties to the next build code and commits the change + # + def bump_build_code + VERSION_FILE.write_version( + version_name: release_version_current, + version_code: build_code_next + ) + commit_version_bump + end + + # Updates the version name in version.properties to the next release version and commits the change + # + def bump_version + VERSION_FILE.write_version( + version_name: release_version_next + ) + commit_version_bump + end + + # Commits the version bump to the version.properties file + # + def commit_version_bump + Fastlane::Helper::GitHelper.commit( + message: 'Bump version number', + files: VERSION_PROPERTIES_PATH + ) + end + + # Returns the current version name from `version.properties` without needing formatting or calculations + # + def version_name_current + VERSION_FILE.read_version_name + end + + # Returns the release version of the app in the format `1.2` or `1.2.3` if it is a hotfix + # + def release_version_current + current_version = VERSION_FORMATTER.parse(version_name_current) + VERSION_FORMATTER.release_version(current_version) + end + + # Returns the next release version of the app in the format `1.2` or `1.2.3` if it is a hotfix + # + def release_version_next + current_version = VERSION_FORMATTER.parse(version_name_current) + release_version_next = VERSION_CALCULATOR.next_release_version(version: current_version) + VERSION_FORMATTER.release_version(release_version_next) + end + + # Returns the current build code of the app + # + def build_code_current + build_code_current = VERSION_FILE.read_version_code + BUILD_CODE_FORMATTER.build_code(build_code: build_code_current) + end + + # Returns the next build code of the app + # + def build_code_next + build_code_current = VERSION_FILE.read_version_code + build_code_next = BUILD_CODE_CALCULATOR.next_build_code(build_code: build_code_current) + BUILD_CODE_FORMATTER.build_code(build_code: build_code_next) + end end From 053a451ff042d66ceefb5064946a23a82bc95027 Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Sat, 26 Jul 2025 02:44:56 +0200 Subject: [PATCH 02/22] Add lanes for building and uploading app releases --- fastlane/Fastfile | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 6703132e..6b9a722e 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -21,6 +21,41 @@ PROTOTYPE_BUILD_DOMAIN = 'https://cdn.a8c-ci.services' PROTOTYPE_BUILD_TYPE = 'release' platform :android do + # Builds a release app bundle .aab + # + lane :build_bundle do + gradle(task: 'clean') + + gradle( + task: 'bundle', + build_type: 'Release' + ) + end + + # Uploads the app bundle to the Google Play Store + # + # @param track [String] The track to upload to. One of: 'internal', 'alpha', 'beta', 'production'. Defaults to 'internal' + # @param release_status [String] The release status. One of: 'completed', 'draft', 'halted', 'inProgress'. Defaults to 'completed' + # @param rollout [String] The percentage of users who should get the update, as a string between '0' and '1'. Defaults to '1' + # @env [String] PLAY_STORE_RAW_JSON_KEY The Google Play Store service account JSON key data + # + lane :upload_to_store do |track: 'internal', release_status: 'completed', rollout: '1'| + require_env_vars!('PLAY_STORE_RAW_JSON_KEY') + + upload_to_play_store( + package_name: 'com.gravatar.app', + aab: File.join(PROJECT_ROOT_FOLDER, 'app', 'build', 'outputs', 'bundle', 'release', 'app-release.aab'), + track: track, + release_status: release_status, + rollout: rollout, + skip_upload_metadata: (track != 'production'), + skip_upload_changelogs: true, + skip_upload_images: true, + skip_upload_screenshots: true, + json_key_data: get_required_env!('PLAY_STORE_RAW_JSON_KEY') + ) + end + # Builds the Gravatar Demo app prototype APK, uploads it to S3, and posts a download link as a comment on the associated pull request. # # Intended for use in CI to provide reviewers with an installable build for testing. From dd2069bb97ce7f8fc6955a0fd39812fb526bad0d Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Mon, 28 Jul 2025 19:49:36 +0200 Subject: [PATCH 03/22] Add pipelines and automation to trigger a new alpha and to build release builds --- .buildkite/commands/release-build.sh | 10 ++ .buildkite/pipeline.yml | 4 +- .buildkite/release-builds.yml | 32 +++++ .../release-pipelines/new-alpha-release.yml | 18 +++ fastlane/Fastfile | 126 +++++++++++++++--- 5 files changed, 166 insertions(+), 24 deletions(-) create mode 100755 .buildkite/commands/release-build.sh create mode 100644 .buildkite/release-builds.yml create mode 100644 .buildkite/release-pipelines/new-alpha-release.yml diff --git a/.buildkite/commands/release-build.sh b/.buildkite/commands/release-build.sh new file mode 100755 index 00000000..7ee0ab99 --- /dev/null +++ b/.buildkite/commands/release-build.sh @@ -0,0 +1,10 @@ +#!/bin/bash -eu + +echo "--- :rubygems: Setting up Gems" +install_gems + +echo "--- :closed_lock_with_key: Installing Secrets" +bundle exec fastlane run configure_apply + +echo "--- :hammer_and_wrench: Building" +bundle exec fastlane build_and_upload_to_play_store diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 6d8445f7..c2b43e1b 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -50,7 +50,7 @@ steps: ./gradlew :app:lintDebug upload_sarif_to_github 'app/build/reports/lint-results-debug.sarif' - plugins: [ $CI_TOOLKIT ] + plugins: [$CI_TOOLKIT] artifact_paths: - "**/build/reports/lint-results*.*" notify: @@ -62,7 +62,7 @@ steps: ./gradlew detekt upload_sarif_to_github 'app/build/reports/detekt/detekt.sarif' - plugins: [ $CI_TOOLKIT ] + plugins: [$CI_TOOLKIT] artifact_paths: - "**/build/reports/detekt/*.*" notify: diff --git a/.buildkite/release-builds.yml b/.buildkite/release-builds.yml new file mode 100644 index 00000000..07a5781d --- /dev/null +++ b/.buildkite/release-builds.yml @@ -0,0 +1,32 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/buildkite/pipeline-schema/main/schema.json +--- + +# This pipeline is meant to be run via the action `buildkite_add_trigger_step`, which calls the buildkite-agent to add it as a trigger step + +agents: + queue: "android" + +steps: + - label: Gradle Wrapper Validation + command: validate_gradle_wrapper + priority: 1 + agents: + queue: linter + + # Wait for Gradle Wrapper to be validated + - wait + + - label: 🕵️‍♂️ Lint + command: ./gradlew lintRelease + key: lint + plugins: [$CI_TOOLKIT] + artifact_paths: + - "**/build/reports/lint-results*.*" + + - label: ":hammer_and_wrench: :android: Build Release and Upload to Play Store" + command: .buildkite/commands/release-build.sh + priority: 1 + depends_on: lint + plugins: [$CI_TOOLKIT] + artifact_paths: + - "app/build/outputs/bundle/release/*.aab" diff --git a/.buildkite/release-pipelines/new-alpha-release.yml b/.buildkite/release-pipelines/new-alpha-release.yml new file mode 100644 index 00000000..9d0fadfb --- /dev/null +++ b/.buildkite/release-pipelines/new-alpha-release.yml @@ -0,0 +1,18 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/buildkite/pipeline-schema/main/schema.json +--- + +steps: + - label: ":rocket: New Alpha Release" + key: new-alpha-release + plugins: [$CI_TOOLKIT] + command: | + echo "--- :robot_face: Use bot for Git operations" + source use-bot-for-git + + echo "--- :ruby: Setup Ruby Tools" + install_gems + + echo "--- :rocket: Create New Alpha" + bundle exec fastlane new_alpha_release skip_confirm:true + agents: + queue: tumblr-metal diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 6b9a722e..344e3b80 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -7,6 +7,11 @@ UI.user_error!('Please run fastlane via `bundle exec`') unless FastlaneCore::Hel ######################################################################## # Constants ######################################################################## +DEFAULT_BRANCH = 'trunk' + +BUILDKITE_ORG_NAME = 'automattic' +BUILDKITE_PIPELINE = 'gravatar-android' + PROJECT_ROOT_FOLDER = File.dirname(File.expand_path(__dir__)) VERSION_PROPERTIES_PATH = File.join(PROJECT_ROOT_FOLDER, 'version.properties') @@ -18,7 +23,7 @@ BUILD_CODE_CALCULATOR = Fastlane::Wpmreleasetoolkit::Versioning::SimpleBuildCode BUILD_CODE_FORMATTER = Fastlane::Wpmreleasetoolkit::Versioning::SimpleBuildCodeFormatter.new PROTOTYPE_BUILD_DOMAIN = 'https://cdn.a8c-ci.services' -PROTOTYPE_BUILD_TYPE = 'release' +RELEASE_BUILD_TYPE = 'Release' platform :android do # Builds a release app bundle .aab @@ -28,7 +33,7 @@ platform :android do gradle( task: 'bundle', - build_type: 'Release' + build_type: RELEASE_BUILD_TYPE ) end @@ -52,7 +57,7 @@ platform :android do skip_upload_changelogs: true, skip_upload_images: true, skip_upload_screenshots: true, - json_key_data: get_required_env!('PLAY_STORE_RAW_JSON_KEY') + json_key_data: ENV.fetch('PLAY_STORE_RAW_JSON_KEY', nil) ) end @@ -78,7 +83,7 @@ platform :android do gradle( task: 'assemble', - build_type: PROTOTYPE_BUILD_TYPE + build_type: RELEASE_BUILD_TYPE ) upload_path = upload_to_s3( @@ -94,7 +99,7 @@ platform :android do app_display_name: 'Gravatar Android', download_url: install_url, metadata: { - 'Build Type': PROTOTYPE_BUILD_TYPE + 'Build Type': RELEASE_BUILD_TYPE }, fold: true ) @@ -105,24 +110,73 @@ platform :android do ) end - def generate_prototype_build_number - if ENV['BUILDKITE'] - commit = ENV.fetch('BUILDKITE_COMMIT', nil)[0, 7] - branch = ENV['BUILDKITE_BRANCH'].parameterize - pr_num = ENV.fetch('BUILDKITE_PULL_REQUEST', nil) + lane :build_and_upload_to_play_store do |track: 'internal'| + build_bundle + upload_to_store(track: track) + end - pr_num == 'false' ? "#{branch}-#{commit}" : "pr#{pr_num}-#{commit}" - else - repo = Git.open(PROJECT_ROOT_FOLDER) - commit = repo.current_branch.parameterize - branch = repo.revparse('HEAD')[0, 7] + ##################################################################################### + # Release lanes & utils + ##################################################################################### + lane :new_alpha_release do |skip_confirm: false| + require_env_vars!('BUILDKITE_TOKEN') + ensure_git_status_clean - "#{branch}-#{commit}" + Fastlane::Helper::GitHelper.checkout_and_pull(DEFAULT_BRANCH) + + UI.important <<~PROMPT + Initiating a new alpha release. + This will: + - Bump the build code from #{build_code_current} to #{build_code_next} + - Trigger a new alpha build in Buildkite + PROMPT + next unless skip_confirm || UI.confirm('Continue?') + + bump_build_code + + push_to_git_remote + + trigger_alpha_build + end + + # Trigger a new alpha build on CI + # + lane :trigger_alpha_build do + require_env_vars!('BUILDKITE_TOKEN') + + trigger_buildkite_build( + branch: DEFAULT_BRANCH, + pipeline: 'release-builds.yml', + message: "Alpha Build (#{build_code_current})" + ) + end + + def trigger_buildkite_build(branch:, pipeline:, message: nil) + environment = { + 'RELEASE_VERSION' => release_version_current + } + + common_args = { + pipeline_file: pipeline, + branch: branch, + message: message || "Build #{pipeline.sub('.yml', '')}", + environment: environment + } + + if is_ci? + buildkite_add_trigger_step(**common_args) + else + # For local development, call Buildkite API to start a new build + buildkite_trigger_build( + buildkite_organization: BUILDKITE_ORG_NAME, + buildkite_pipeline: BUILDKITE_PIPELINE, + **common_args + ) end end ##################################################################################### - # Version Methods + # Versioning utils ##################################################################################### # Updates the build code in version.properties to the next build code and commits the change @@ -132,7 +186,7 @@ platform :android do version_name: release_version_current, version_code: build_code_next ) - commit_version_bump + commit_version_update(message: '[skip ci] Bump build code') end # Updates the version name in version.properties to the next release version and commits the change @@ -141,14 +195,14 @@ platform :android do VERSION_FILE.write_version( version_name: release_version_next ) - commit_version_bump + commit_version_update(message: '[skip ci] Bump app version') end - # Commits the version bump to the version.properties file + # Commits the version update to the version.properties file # - def commit_version_bump + def commit_version_update(message:) Fastlane::Helper::GitHelper.commit( - message: 'Bump version number', + message: message, files: VERSION_PROPERTIES_PATH ) end @@ -188,4 +242,32 @@ platform :android do build_code_next = BUILD_CODE_CALCULATOR.next_build_code(build_code: build_code_current) BUILD_CODE_FORMATTER.build_code(build_code: build_code_next) end + + # Generates a build number for the prototype build + # + def generate_prototype_build_number + if ENV['BUILDKITE'] + commit = ENV.fetch('BUILDKITE_COMMIT', nil)[0, 7] + branch = ENV['BUILDKITE_BRANCH'].parameterize + pr_num = ENV.fetch('BUILDKITE_PULL_REQUEST', nil) + + pr_num == 'false' ? "#{branch}-#{commit}" : "pr#{pr_num}-#{commit}" + else + repo = Git.open(PROJECT_ROOT_FOLDER) + commit = repo.current_branch.parameterize + branch = repo.revparse('HEAD')[0, 7] + + "#{branch}-#{commit}" + end + end + + ##################################################################################### + # Other utils + ##################################################################################### + + def require_env_vars!(*keys) + keys.each do |key| + UI.user_error!("Environment variable '#{key}' is not set.") unless ENV.key?(key) + end + end end From 69666a4107d00830965bbba563d39bf9727e63d6 Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Tue, 29 Jul 2025 11:31:42 +0200 Subject: [PATCH 04/22] Use require_env_vars! to validate required ENV vars when building a prototype --- fastlane/Fastfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 344e3b80..ec9163e3 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -68,7 +68,7 @@ platform :android do # @env [String] BUILDKITE_PULL_REQUEST The pull request number. # lane :build_and_upload_prototype_build do - UI.user_error!("'BUILDKITE_ARTIFACTS_S3_BUCKET' must be defined as an environment variable.") unless ENV['BUILDKITE_ARTIFACTS_S3_BUCKET'] + require_env_vars!('BUILDKITE_ARTIFACTS_S3_BUCKET') comment_params = { project: 'Automattic/Gravatar-Android', From 0b38724561d2ccce91c26136a2219af9c46f909d Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Tue, 29 Jul 2025 13:31:37 +0200 Subject: [PATCH 05/22] Improve release lanes to better run locally --- .buildkite/commands/release-build.sh | 2 +- fastlane/Fastfile | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.buildkite/commands/release-build.sh b/.buildkite/commands/release-build.sh index 7ee0ab99..956c87a4 100755 --- a/.buildkite/commands/release-build.sh +++ b/.buildkite/commands/release-build.sh @@ -6,5 +6,5 @@ install_gems echo "--- :closed_lock_with_key: Installing Secrets" bundle exec fastlane run configure_apply -echo "--- :hammer_and_wrench: Building" +echo "--- :hammer_and_wrench: Building and Uploading to Play Store" bundle exec fastlane build_and_upload_to_play_store diff --git a/fastlane/Fastfile b/fastlane/Fastfile index ec9163e3..f502276c 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -122,32 +122,33 @@ platform :android do require_env_vars!('BUILDKITE_TOKEN') ensure_git_status_clean - Fastlane::Helper::GitHelper.checkout_and_pull(DEFAULT_BRANCH) - UI.important <<~PROMPT Initiating a new alpha release. This will: + - Checkout and pull the #{DEFAULT_BRANCH} branch (if running in CI) - Bump the build code from #{build_code_current} to #{build_code_next} - Trigger a new alpha build in Buildkite PROMPT next unless skip_confirm || UI.confirm('Continue?') + Fastlane::Helper::GitHelper.checkout_and_pull(DEFAULT_BRANCH) if is_ci? + bump_build_code push_to_git_remote - trigger_alpha_build + trigger_release_build end # Trigger a new alpha build on CI # - lane :trigger_alpha_build do + lane :trigger_release_build do require_env_vars!('BUILDKITE_TOKEN') trigger_buildkite_build( - branch: DEFAULT_BRANCH, + branch: git_branch, pipeline: 'release-builds.yml', - message: "Alpha Build (#{build_code_current})" + message: "Release Build (#{build_code_current})" ) end From 5880bddfe16fdd514e101f5d77a3cc4cb245dc16 Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Tue, 29 Jul 2025 18:04:32 +0200 Subject: [PATCH 06/22] Improve lane defaults for releasing --- fastlane/Fastfile | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index f502276c..66ae23f0 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -39,12 +39,12 @@ platform :android do # Uploads the app bundle to the Google Play Store # - # @param track [String] The track to upload to. One of: 'internal', 'alpha', 'beta', 'production'. Defaults to 'internal' - # @param release_status [String] The release status. One of: 'completed', 'draft', 'halted', 'inProgress'. Defaults to 'completed' - # @param rollout [String] The percentage of users who should get the update, as a string between '0' and '1'. Defaults to '1' + # @param track [String] The track to upload to. One of: 'internal', 'alpha', 'beta', 'production'. + # @param release_status [String] The release status. One of: 'completed', 'draft', 'halted', 'inProgress'. + # @param rollout [String] The percentage of users who should get the update, as a string between '0' and '1'. # @env [String] PLAY_STORE_RAW_JSON_KEY The Google Play Store service account JSON key data # - lane :upload_to_store do |track: 'internal', release_status: 'completed', rollout: '1'| + lane :upload_to_store do |track:, release_status:, rollout:| require_env_vars!('PLAY_STORE_RAW_JSON_KEY') upload_to_play_store( @@ -110,9 +110,10 @@ platform :android do ) end - lane :build_and_upload_to_play_store do |track: 'internal'| + lane :build_and_upload_to_play_store do |track: 'internal', release_status: 'draft'| + # TODO using `internal`` track with `draft` releases by default while the release itself is in draft mode build_bundle - upload_to_store(track: track) + upload_to_store(track: track, release_status: release_status, rollout: '1') end ##################################################################################### @@ -125,7 +126,7 @@ platform :android do UI.important <<~PROMPT Initiating a new alpha release. This will: - - Checkout and pull the #{DEFAULT_BRANCH} branch (if running in CI) + - Checkout and pull the #{DEFAULT_BRANCH} branch (if running on CI) - Bump the build code from #{build_code_current} to #{build_code_next} - Trigger a new alpha build in Buildkite PROMPT From 413c03c621e3ce6f4fca67d81e90697d55904e57 Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Tue, 29 Jul 2025 15:41:35 +0200 Subject: [PATCH 07/22] Move helper functions to end of file after platform --- fastlane/Fastfile | 168 +++++++++++++++++++++++----------------------- 1 file changed, 84 insertions(+), 84 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 66ae23f0..80fbc2d4 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -111,7 +111,7 @@ platform :android do end lane :build_and_upload_to_play_store do |track: 'internal', release_status: 'draft'| - # TODO using `internal`` track with `draft` releases by default while the release itself is in draft mode + # TODO: using `internal`` track with `draft` releases by default while the release itself is in draft mode build_bundle upload_to_store(track: track, release_status: release_status, rollout: '1') end @@ -176,100 +176,100 @@ platform :android do ) end end +end - ##################################################################################### - # Versioning utils - ##################################################################################### - - # Updates the build code in version.properties to the next build code and commits the change - # - def bump_build_code - VERSION_FILE.write_version( - version_name: release_version_current, - version_code: build_code_next - ) - commit_version_update(message: '[skip ci] Bump build code') - end - - # Updates the version name in version.properties to the next release version and commits the change - # - def bump_version - VERSION_FILE.write_version( - version_name: release_version_next - ) - commit_version_update(message: '[skip ci] Bump app version') - end - - # Commits the version update to the version.properties file - # - def commit_version_update(message:) - Fastlane::Helper::GitHelper.commit( - message: message, - files: VERSION_PROPERTIES_PATH - ) - end +##################################################################################### +# Versioning utils +##################################################################################### + +# Updates the build code in version.properties to the next build code and commits the change +# +def bump_build_code + VERSION_FILE.write_version( + version_name: release_version_current, + version_code: build_code_next + ) + commit_version_update(message: '[skip ci] Bump build code') +end - # Returns the current version name from `version.properties` without needing formatting or calculations - # - def version_name_current - VERSION_FILE.read_version_name - end +# Updates the version name in version.properties to the next release version and commits the change +# +def bump_version + VERSION_FILE.write_version( + version_name: release_version_next + ) + commit_version_update(message: '[skip ci] Bump app version') +end - # Returns the release version of the app in the format `1.2` or `1.2.3` if it is a hotfix - # - def release_version_current - current_version = VERSION_FORMATTER.parse(version_name_current) - VERSION_FORMATTER.release_version(current_version) - end +# Commits the version update to the version.properties file +# +def commit_version_update(message:) + Fastlane::Helper::GitHelper.commit( + message: message, + files: VERSION_PROPERTIES_PATH + ) +end - # Returns the next release version of the app in the format `1.2` or `1.2.3` if it is a hotfix - # - def release_version_next - current_version = VERSION_FORMATTER.parse(version_name_current) - release_version_next = VERSION_CALCULATOR.next_release_version(version: current_version) - VERSION_FORMATTER.release_version(release_version_next) - end +# Returns the current version name from `version.properties` without needing formatting or calculations +# +def version_name_current + VERSION_FILE.read_version_name +end - # Returns the current build code of the app - # - def build_code_current - build_code_current = VERSION_FILE.read_version_code - BUILD_CODE_FORMATTER.build_code(build_code: build_code_current) - end +# Returns the release version of the app in the format `1.2` or `1.2.3` if it is a hotfix +# +def release_version_current + current_version = VERSION_FORMATTER.parse(version_name_current) + VERSION_FORMATTER.release_version(current_version) +end - # Returns the next build code of the app - # - def build_code_next - build_code_current = VERSION_FILE.read_version_code - build_code_next = BUILD_CODE_CALCULATOR.next_build_code(build_code: build_code_current) - BUILD_CODE_FORMATTER.build_code(build_code: build_code_next) - end +# Returns the next release version of the app in the format `1.2` or `1.2.3` if it is a hotfix +# +def release_version_next + current_version = VERSION_FORMATTER.parse(version_name_current) + release_version_next = VERSION_CALCULATOR.next_release_version(version: current_version) + VERSION_FORMATTER.release_version(release_version_next) +end - # Generates a build number for the prototype build - # - def generate_prototype_build_number - if ENV['BUILDKITE'] - commit = ENV.fetch('BUILDKITE_COMMIT', nil)[0, 7] - branch = ENV['BUILDKITE_BRANCH'].parameterize - pr_num = ENV.fetch('BUILDKITE_PULL_REQUEST', nil) +# Returns the current build code of the app +# +def build_code_current + build_code_current = VERSION_FILE.read_version_code + BUILD_CODE_FORMATTER.build_code(build_code: build_code_current) +end - pr_num == 'false' ? "#{branch}-#{commit}" : "pr#{pr_num}-#{commit}" - else - repo = Git.open(PROJECT_ROOT_FOLDER) - commit = repo.current_branch.parameterize - branch = repo.revparse('HEAD')[0, 7] +# Returns the next build code of the app +# +def build_code_next + build_code_current = VERSION_FILE.read_version_code + build_code_next = BUILD_CODE_CALCULATOR.next_build_code(build_code: build_code_current) + BUILD_CODE_FORMATTER.build_code(build_code: build_code_next) +end - "#{branch}-#{commit}" - end +# Generates a build number for the prototype build +# +def generate_prototype_build_number + if ENV['BUILDKITE'] + commit = ENV.fetch('BUILDKITE_COMMIT', nil)[0, 7] + branch = ENV['BUILDKITE_BRANCH'].parameterize + pr_num = ENV.fetch('BUILDKITE_PULL_REQUEST', nil) + + pr_num == 'false' ? "#{branch}-#{commit}" : "pr#{pr_num}-#{commit}" + else + repo = Git.open(PROJECT_ROOT_FOLDER) + commit = repo.current_branch.parameterize + branch = repo.revparse('HEAD')[0, 7] + + "#{branch}-#{commit}" end +end - ##################################################################################### - # Other utils - ##################################################################################### +##################################################################################### +# Other utils +##################################################################################### - def require_env_vars!(*keys) - keys.each do |key| - UI.user_error!("Environment variable '#{key}' is not set.") unless ENV.key?(key) - end +def require_env_vars!(*keys) + keys.each do |key| + UI.user_error!("Environment variable '#{key}' is not set.") unless ENV.key?(key) end end From e39e4c95804c7a4e86813bd43b588ddcd29eda6c Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Tue, 29 Jul 2025 18:12:41 +0200 Subject: [PATCH 08/22] [skip ci] Bump build code --- version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.properties b/version.properties index 773d02d7..b1b23f2e 100644 --- a/version.properties +++ b/version.properties @@ -1,2 +1,2 @@ versionName=0.1 -versionCode=4 \ No newline at end of file +versionCode=5 \ No newline at end of file From ebef7ba7c1a4bf29ca4008ca99c3e29cde18adcb Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Tue, 29 Jul 2025 18:41:22 +0200 Subject: [PATCH 09/22] Update code to only specify a rollout when the track isn't draft --- fastlane/Fastfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 80fbc2d4..94aec523 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -113,7 +113,7 @@ platform :android do lane :build_and_upload_to_play_store do |track: 'internal', release_status: 'draft'| # TODO: using `internal`` track with `draft` releases by default while the release itself is in draft mode build_bundle - upload_to_store(track: track, release_status: release_status, rollout: '1') + upload_to_store(track: track, release_status: release_status, rollout: release_status == 'draft' ? nil : '1') end ##################################################################################### From 5fbbf08ce62ac3c8beb34f23a6b25935b266a9a3 Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Tue, 29 Jul 2025 18:41:34 +0200 Subject: [PATCH 10/22] [skip ci] Bump build code --- version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.properties b/version.properties index b1b23f2e..d4223ef1 100644 --- a/version.properties +++ b/version.properties @@ -1,2 +1,2 @@ versionName=0.1 -versionCode=5 \ No newline at end of file +versionCode=6 \ No newline at end of file From 0282ff7a2d29ac8fbf449d4eb8834a7e78018c91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?He=CC=81ctor=20Abraham?= Date: Wed, 30 Jul 2025 08:53:17 +0200 Subject: [PATCH 11/22] [skip ci] Bump build code --- version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.properties b/version.properties index d4223ef1..ba3bda99 100644 --- a/version.properties +++ b/version.properties @@ -1,2 +1,2 @@ versionName=0.1 -versionCode=6 \ No newline at end of file +versionCode=7 \ No newline at end of file From 36516eda09ab20053a73d1c539f3d6daa8e3814c Mon Sep 17 00:00:00 2001 From: "Ian G. Maia" Date: Thu, 31 Jul 2025 16:48:03 +0200 Subject: [PATCH 12/22] Apply suggestions from code review Co-authored-by: Olivier Halligon --- fastlane/Fastfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 94aec523..93566679 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -54,7 +54,7 @@ platform :android do release_status: release_status, rollout: rollout, skip_upload_metadata: (track != 'production'), - skip_upload_changelogs: true, + skip_upload_changelogs: (track != 'production'), skip_upload_images: true, skip_upload_screenshots: true, json_key_data: ENV.fetch('PLAY_STORE_RAW_JSON_KEY', nil) @@ -111,7 +111,7 @@ platform :android do end lane :build_and_upload_to_play_store do |track: 'internal', release_status: 'draft'| - # TODO: using `internal`` track with `draft` releases by default while the release itself is in draft mode + # TODO: using `internal` track with `draft` releases by default while the release itself is in draft mode build_bundle upload_to_store(track: track, release_status: release_status, rollout: release_status == 'draft' ? nil : '1') end From f57f31c191cbab9f93daf4c80fc95eebc42d088b Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Thu, 31 Jul 2025 21:12:52 +0200 Subject: [PATCH 13/22] Use new name for the Play Store Upload Key in the environment vars --- fastlane/Fastfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 93566679..fb7fbea9 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -42,10 +42,10 @@ platform :android do # @param track [String] The track to upload to. One of: 'internal', 'alpha', 'beta', 'production'. # @param release_status [String] The release status. One of: 'completed', 'draft', 'halted', 'inProgress'. # @param rollout [String] The percentage of users who should get the update, as a string between '0' and '1'. - # @env [String] PLAY_STORE_RAW_JSON_KEY The Google Play Store service account JSON key data + # @env [String] PLAY_STORE_SERVICE_ACCOUNT_UPLOAD_KEY The Google Play Store service account JSON key data # lane :upload_to_store do |track:, release_status:, rollout:| - require_env_vars!('PLAY_STORE_RAW_JSON_KEY') + require_env_vars!('PLAY_STORE_SERVICE_ACCOUNT_UPLOAD_KEY') upload_to_play_store( package_name: 'com.gravatar.app', @@ -57,7 +57,7 @@ platform :android do skip_upload_changelogs: (track != 'production'), skip_upload_images: true, skip_upload_screenshots: true, - json_key_data: ENV.fetch('PLAY_STORE_RAW_JSON_KEY', nil) + json_key_data: ENV.fetch('PLAY_STORE_SERVICE_ACCOUNT_UPLOAD_KEY', nil) ) end @@ -149,7 +149,7 @@ platform :android do trigger_buildkite_build( branch: git_branch, pipeline: 'release-builds.yml', - message: "Release Build (#{build_code_current})" + message: "Release Build #{release_version_current} (#{build_code_current})" ) end From d5b7e5d29fb5644071ab9b990c3ed786f8693ec5 Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Fri, 1 Aug 2025 19:09:09 +0200 Subject: [PATCH 14/22] Add more detailed Yard docs --- fastlane/Fastfile | 49 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index fb7fbea9..38db8f54 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -26,7 +26,9 @@ PROTOTYPE_BUILD_DOMAIN = 'https://cdn.a8c-ci.services' RELEASE_BUILD_TYPE = 'Release' platform :android do - # Builds a release app bundle .aab + # Builds a release app bundle (.aab) for the Gravatar Android app + # + # This lane cleans the project and builds a release bundle (.aab) that can be uploaded to the Google Play Store. # lane :build_bundle do gradle(task: 'clean') @@ -39,11 +41,19 @@ platform :android do # Uploads the app bundle to the Google Play Store # - # @param track [String] The track to upload to. One of: 'internal', 'alpha', 'beta', 'production'. - # @param release_status [String] The release status. One of: 'completed', 'draft', 'halted', 'inProgress'. - # @param rollout [String] The percentage of users who should get the update, as a string between '0' and '1'. + # This lane uploads a previously built app bundle to the specified track on Google Play Store + # with the given release status and rollout percentage. + # + # @param track [String] The track to upload to. One of: 'internal', 'alpha', 'beta', 'production' + # @param release_status [String] The release status. One of: 'completed', 'draft', 'halted', 'inProgress' + # @param rollout [String] The percentage of users who should get the update, as a string between '0' and '1' # @env [String] PLAY_STORE_SERVICE_ACCOUNT_UPLOAD_KEY The Google Play Store service account JSON key data # + # @example Upload to internal track as draft + # upload_to_store(track: 'internal', release_status: 'draft', rollout: nil) + # @example Upload to production with 50% rollout + # upload_to_store(track: 'production', release_status: 'completed', rollout: '0.5') + # lane :upload_to_store do |track:, release_status:, rollout:| require_env_vars!('PLAY_STORE_SERVICE_ACCOUNT_UPLOAD_KEY') @@ -61,11 +71,10 @@ platform :android do ) end - # Builds the Gravatar Demo app prototype APK, uploads it to S3, and posts a download link as a comment on the associated pull request. + # Builds the Gravatar Demo app prototype APK, uploads it to S3, and posts a download link as a comment on the associated pull request # - # Intended for use in CI to provide reviewers with an installable build for testing. - # @env [String] BUILDKITE_ARTIFACTS_S3_BUCKET The S3 bucket to upload artifacts to. Must be set. - # @env [String] BUILDKITE_PULL_REQUEST The pull request number. + # This lane is intended for use in CI to provide reviewers with an installable build for testing. + # It builds a release APK, uploads it to S3, and posts the download link as a PR comment. # lane :build_and_upload_prototype_build do require_env_vars!('BUILDKITE_ARTIFACTS_S3_BUCKET') @@ -110,6 +119,15 @@ platform :android do ) end + # Builds an app bundle and uploads it to the Google Play Store + # + # This is a convenience lane that combines building the app bundle and uploading it to the Play Store. + # It uses internal track with draft releases by default while the release process is being refined. + # + # @param track [String] The Play Store track to upload to (default: 'internal') + # @param release_status [String] The Play Store release status (default: 'draft') + # @see upload_to_store + # lane :build_and_upload_to_play_store do |track: 'internal', release_status: 'draft'| # TODO: using `internal` track with `draft` releases by default while the release itself is in draft mode build_bundle @@ -117,8 +135,16 @@ platform :android do end ##################################################################################### - # Release lanes & utils + # Release lanes ##################################################################################### + + # Initiates a new alpha release by bumping the build code and triggering a release build + # + # This lane will checkout and pull the trunk branch (if running on CI), bump the build code, + # push the changes to the remote repository, and trigger a new alpha build in Buildkite. + # + # @param skip_confirm [Boolean] Skip the confirmation prompt (default: false) + # lane :new_alpha_release do |skip_confirm: false| require_env_vars!('BUILDKITE_TOKEN') ensure_git_status_clean @@ -141,7 +167,10 @@ platform :android do trigger_release_build end - # Trigger a new alpha build on CI + # Triggers a new alpha build on CI using Buildkite + # + # This lane triggers a release build in Buildkite for the current git branch. + # The build will use the current release version and build code. # lane :trigger_release_build do require_env_vars!('BUILDKITE_TOKEN') From 584f38febf7816b378b5b6025214bc377ed27f3d Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Fri, 1 Aug 2025 20:18:46 +0200 Subject: [PATCH 15/22] Use `DerivedBuildCodeFormatter` for build code calculations --- fastlane/Fastfile | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 38db8f54..d364cae1 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -19,8 +19,9 @@ VERSION_FILE = Fastlane::Wpmreleasetoolkit::Versioning::AndroidVersionFile.new(v VERSION_CALCULATOR = Fastlane::Wpmreleasetoolkit::Versioning::SemanticVersionCalculator.new VERSION_FORMATTER = Fastlane::Wpmreleasetoolkit::Versioning::RCNotationVersionFormatter.new -BUILD_CODE_CALCULATOR = Fastlane::Wpmreleasetoolkit::Versioning::SimpleBuildCodeCalculator.new -BUILD_CODE_FORMATTER = Fastlane::Wpmreleasetoolkit::Versioning::SimpleBuildCodeFormatter.new +# Using DerivedBuildCodeFormatter to derive build codes from version name (format: 1XXYYZZNNN) +# This eliminates the need for manual build code incrementing and provides deterministic versioning +BUILD_CODE_FORMATTER = Fastlane::Wpmreleasetoolkit::Versioning::DerivedBuildCodeFormatter.new PROTOTYPE_BUILD_DOMAIN = 'https://cdn.a8c-ci.services' RELEASE_BUILD_TYPE = 'Release' @@ -211,7 +212,7 @@ end # Versioning utils ##################################################################################### -# Updates the build code in version.properties to the next build code and commits the change +# Updates the build code in version.properties by incrementing the build number and deriving the new build code # def bump_build_code VERSION_FILE.write_version( @@ -260,19 +261,25 @@ def release_version_next VERSION_FORMATTER.release_version(release_version_next) end -# Returns the current build code of the app +# Returns the current build code of the app derived from the current version # def build_code_current - build_code_current = VERSION_FILE.read_version_code - BUILD_CODE_FORMATTER.build_code(build_code: build_code_current) + current_version = VERSION_FORMATTER.parse(version_name_current) + BUILD_CODE_FORMATTER.build_code(version: current_version) end -# Returns the next build code of the app +# Returns the next build code of the app derived from the current version with incremented build number # def build_code_next - build_code_current = VERSION_FILE.read_version_code - build_code_next = BUILD_CODE_CALCULATOR.next_build_code(build_code: build_code_current) - BUILD_CODE_FORMATTER.build_code(build_code: build_code_next) + current_version = VERSION_FORMATTER.parse(version_name_current) + # Create a new version with incremented build number + next_version = Fastlane::Models::AppVersion.new( + current_version.major, + current_version.minor, + current_version.patch, + current_version.build_number + 1 + ) + BUILD_CODE_FORMATTER.build_code(version: next_version) end # Generates a build number for the prototype build From ded34f8db9b19964a8b0a026d43be05bfe426f9b Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Fri, 1 Aug 2025 20:19:28 +0200 Subject: [PATCH 16/22] [skip ci] Bump build code --- version.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.properties b/version.properties index ba3bda99..20a57342 100644 --- a/version.properties +++ b/version.properties @@ -1,2 +1,2 @@ -versionName=0.1 -versionCode=7 \ No newline at end of file +versionName=0.2 +versionCode=100020001 \ No newline at end of file From fb5bbcfe454440854266886cabfed79c520640af Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Tue, 5 Aug 2025 23:31:10 +0200 Subject: [PATCH 17/22] Upload to internal track with full rollout --- .buildkite/commands/release-build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.buildkite/commands/release-build.sh b/.buildkite/commands/release-build.sh index 956c87a4..081c0440 100755 --- a/.buildkite/commands/release-build.sh +++ b/.buildkite/commands/release-build.sh @@ -7,4 +7,4 @@ echo "--- :closed_lock_with_key: Installing Secrets" bundle exec fastlane run configure_apply echo "--- :hammer_and_wrench: Building and Uploading to Play Store" -bundle exec fastlane build_and_upload_to_play_store +bundle exec fastlane build_and_upload_to_play_store track:'internal' release_status:'completed' From 66f8616fef5de2a1c69878b23ea1baeaae7561c0 Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Tue, 5 Aug 2025 23:32:15 +0200 Subject: [PATCH 18/22] Update release-toolkit --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 926ccb20..89cdc436 100644 --- a/Gemfile +++ b/Gemfile @@ -4,4 +4,4 @@ source 'https://rubygems.org' gem 'danger-dangermattic', '~> 1.2' gem 'fastlane', '~> 2.228' -gem 'fastlane-plugin-wpmreleasetoolkit', '~> 13.3' +gem 'fastlane-plugin-wpmreleasetoolkit', '~> 13.4' diff --git a/Gemfile.lock b/Gemfile.lock index a90fd1c9..3a38700b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -167,7 +167,7 @@ GEM xcodeproj (>= 1.13.0, < 2.0.0) xcpretty (~> 0.4.1) xcpretty-travis-formatter (>= 0.0.3, < 2.0.0) - fastlane-plugin-wpmreleasetoolkit (13.3.1) + fastlane-plugin-wpmreleasetoolkit (13.4.0) activesupport (>= 6.1.7.1) buildkit (~> 1.5) chroma (= 0.2.0) @@ -354,7 +354,7 @@ PLATFORMS DEPENDENCIES danger-dangermattic (~> 1.2) fastlane (~> 2.228) - fastlane-plugin-wpmreleasetoolkit (~> 13.3) + fastlane-plugin-wpmreleasetoolkit (~> 13.4) BUNDLED WITH 2.6.3 From da88418b135855e84b6100507ac635735cb2f7d4 Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Tue, 5 Aug 2025 23:33:56 +0200 Subject: [PATCH 19/22] Update build code formatter init --- fastlane/Fastfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index d364cae1..c567a7cb 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -19,9 +19,9 @@ VERSION_FILE = Fastlane::Wpmreleasetoolkit::Versioning::AndroidVersionFile.new(v VERSION_CALCULATOR = Fastlane::Wpmreleasetoolkit::Versioning::SemanticVersionCalculator.new VERSION_FORMATTER = Fastlane::Wpmreleasetoolkit::Versioning::RCNotationVersionFormatter.new -# Using DerivedBuildCodeFormatter to derive build codes from version name (format: 1XXYYZZNNN) +# Using DerivedBuildCodeFormatter to derive build codes from version name (format: 1XXYYYZNN) # This eliminates the need for manual build code incrementing and provides deterministic versioning -BUILD_CODE_FORMATTER = Fastlane::Wpmreleasetoolkit::Versioning::DerivedBuildCodeFormatter.new +BUILD_CODE_FORMATTER = Fastlane::Wpmreleasetoolkit::Versioning::DerivedBuildCodeFormatter.new(prefix: '1', major_digits: 2, minor_digits: 3, patch_digits: 1, build_digits: 2) PROTOTYPE_BUILD_DOMAIN = 'https://cdn.a8c-ci.services' RELEASE_BUILD_TYPE = 'Release' From c3090ac51440618d3493a8444d5045e9b120968c Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Tue, 5 Aug 2025 23:44:34 +0200 Subject: [PATCH 20/22] Use version 0.21, given the build code `100020001` (0.20 in the new versioning scheme) was used --- version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.properties b/version.properties index 20a57342..59e4b093 100644 --- a/version.properties +++ b/version.properties @@ -1,2 +1,2 @@ -versionName=0.2 +versionName=0.21 versionCode=100020001 \ No newline at end of file From ca3fc2e299996e5b0f6d9797f1286ac5ad431011 Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Wed, 6 Aug 2025 12:32:59 +0200 Subject: [PATCH 21/22] [skip ci] Bump build code --- version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.properties b/version.properties index 59e4b093..d3c0e496 100644 --- a/version.properties +++ b/version.properties @@ -1,2 +1,2 @@ versionName=0.21 -versionCode=100020001 \ No newline at end of file +versionCode=100021001 \ No newline at end of file From 9a5011e5964e86b40bd094f44163ebb2ca2791d8 Mon Sep 17 00:00:00 2001 From: "Ian G. Maia" Date: Wed, 6 Aug 2025 13:15:34 +0200 Subject: [PATCH 22/22] Improve comment Co-authored-by: Olivier Halligon --- fastlane/Fastfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index c567a7cb..0a064a6d 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -20,7 +20,8 @@ VERSION_FILE = Fastlane::Wpmreleasetoolkit::Versioning::AndroidVersionFile.new(v VERSION_CALCULATOR = Fastlane::Wpmreleasetoolkit::Versioning::SemanticVersionCalculator.new VERSION_FORMATTER = Fastlane::Wpmreleasetoolkit::Versioning::RCNotationVersionFormatter.new # Using DerivedBuildCodeFormatter to derive build codes from version name (format: 1XXYYYZNN) -# This eliminates the need for manual build code incrementing and provides deterministic versioning +# This eliminates the need for manual build code incrementing, provides deterministic versioning, +# and also avoids the need to do a new beta for version N+1 every time we do a hotfix for version N BUILD_CODE_FORMATTER = Fastlane::Wpmreleasetoolkit::Versioning::DerivedBuildCodeFormatter.new(prefix: '1', major_digits: 2, minor_digits: 3, patch_digits: 1, build_digits: 2) PROTOTYPE_BUILD_DOMAIN = 'https://cdn.a8c-ci.services'