diff --git a/fastlane/Fastfile b/fastlane/Fastfile index b74dd9d5e88..d5ad76d2393 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -62,7 +62,7 @@ SUPPORTED_LOCALES = [ Dotenv.load(USER_ENV_FILE_PATH) DEFAULT_BRANCH = 'main' ENV['SUPPLY_UPLOAD_MAX_RETRIES'] = '5' -GH_REPOSITORY = 'automattic/pocket-casts-android' +GITHUB_REPO = 'automattic/pocket-casts-android' APPS_APP = 'app' APPS_AUTOMOTIVE = 'automotive' APPS_WEAR = 'wear' @@ -144,12 +144,12 @@ platform :android do # We cannot use the `copy_branch_protection` action here as it would create a branch protection rule with the same # restrictions we have in `main`, and the release managers wouldn't be able to push due to permissions. # This should be changed only when we have PC Android releases done on CI, when the CI bot is the one running `git push`. - set_branch_protection(repository: GH_REPOSITORY, branch: "release/#{new_version}") + set_branch_protection(repository: GITHUB_REPO, branch: "release/#{new_version}") begin # Move PRs to next milestone moved_prs = update_assigned_milestone( - repository: GH_REPOSITORY, + repository: GITHUB_REPO, from_milestone: new_version, to_milestone: release_version_next, comment: "Version `#{new_version}` has now entered code-freeze, so the milestone of this PR has been updated to `#{release_version_next}`." @@ -158,7 +158,7 @@ platform :android do # Add ❄️ marker to milestone title to indicate we entered code-freeze set_milestone_frozen_marker( - repository: GH_REPOSITORY, + repository: GITHUB_REPO, milestone: new_version ) rescue StandardError => e @@ -290,75 +290,6 @@ platform :android do create_backmerge_pr end - # @param branch_to_build [String] The branch to build. Defaults to the current git branch. - # - lane :trigger_release_build do |branch_to_build: git_branch| - buildkite_trigger_build( - buildkite_organization: 'automattic', - buildkite_pipeline: 'pocket-casts-android', - branch: branch_to_build, - pipeline_file: 'release-builds.yml' - ) - end - - # Builds and uploads a new build to Google Play (without releasing it) - # - # - Uses the current version to decide if this is a beta or production build - # - Builds the apps for external distribution - # - Uploads the builds to 'beta' or 'production' Play Store channel (but does not release it) - # - Creates draft Github release - # - # @param skip_confirm [Boolean] If true, avoids any interactive prompt - # @param skip_prechecks [Boolean] If true, skips android_build_preflight - # @param create_gh_release [Boolean] If true, creates a draft GitHub release - # - lane :build_and_upload_to_play_store do |skip_prechecks: false, skip_confirm: false, create_gh_release: false| - version = version_name_current - build_code = build_code_current - is_beta = beta_version?(version) - unless skip_prechecks - # Match branch names that begin with `release/` - ensure_git_branch(branch: '^release/') unless is_ci - - UI.important("Building version #{version_name_current} (#{build_code_current}) for upload to Google Play Console") - UI.user_error!("Terminating as requested. Don't forget to run the remainder of this automation manually.") unless skip_confirm || UI.confirm('Do you want to continue?') - - # Check local repo status - ensure_git_status_clean unless is_ci - - android_build_preflight - end - - release_assets = [] - - APPS.each do |app| - build_bundle(app: app, version: version, build_code: build_code) - - aab_artifact_path = aab_artifact_path(app, version) - UI.error("Unable to find a build artifact at #{aab_artifact_path}") unless File.exist? aab_artifact_path - - track = play_store_track(app: app, is_beta: is_beta) - upload_to_play_store( - **UPLOAD_TO_PLAY_STORE_COMMON_OPTIONS, - aab: aab_artifact_path, - track: track, - release_status: 'draft' - ) - release_assets << aab_artifact_path - - signed_apk_artifact_path = signed_apk_artifact_path(app, version) - download_universal_apk_from_google_play( - package_name: APP_PACKAGE_NAME, - version_code: version_code_for_app(app: app, version_code: build_code), - destination: signed_apk_artifact_path, - json_key: UPLOAD_TO_PLAY_STORE_JSON_KEY - ) - release_assets << signed_apk_artifact_path - end - - create_gh_release(version: version, prerelease: is_beta, release_assets: release_assets.compact) if create_gh_release - end - # Update the rollout of all 3 variants (app, automotive, wear) of the current version to the given value # # @param percent [Float] The rollout percentage, between 0 and 1 @@ -424,16 +355,125 @@ platform :android do version = release_version_current # Wrap up - remove_branch_protection(repository: GH_REPOSITORY, branch: "release/#{version}") - set_milestone_frozen_marker(repository: GH_REPOSITORY, milestone: version, freeze: false) - create_new_milestone(repository: GH_REPOSITORY, need_appstore_submission: true) - close_milestone(repository: GH_REPOSITORY, milestone: version) + remove_branch_protection(repository: GITHUB_REPO, branch: "release/#{version}") + set_milestone_frozen_marker(repository: GITHUB_REPO, milestone: version, freeze: false) + create_new_milestone(repository: GITHUB_REPO, need_appstore_submission: true) + close_milestone(repository: GITHUB_REPO, milestone: version) push_to_git_remote(tags: false) trigger_release_build(branch_to_build: "release/#{version}") create_backmerge_pr end + # This lane publishes a release on GitHub and creates a PR to backmerge the current release branch into the next release/ branch + # + # @param [Boolean] skip_confirm (default: false) If set, will skip the confirmation prompt before running the rest of the lane + # + lane :publish_release do |skip_confirm: false| + ensure_git_status_clean + ensure_git_branch(branch: '^release/') + + version_number = release_version_current + + current_branch = "release/#{version_number}" + next_release_branch = "release/#{release_version_next}" + + UI.important <<~PROMPT + Publish the #{version_number} release. This will: + - Publish the existing draft `#{version_number}` release on GitHub + - Which will also have GitHub create the associated git tag, pointing to the tip of the branch + - If the release branch for the next version `#{next_release_branch}` already exists, backmerge `#{current_branch}` into it + - If needed, backmerge `#{current_branch}` back into `#{DEFAULT_BRANCH}` + - Delete the `#{current_branch}` branch + PROMPT + UI.user_error!("Terminating as requested. Don't forget to run the remainder of this automation manually.") unless skip_confirm || UI.confirm('Do you want to continue?') + + UI.important "Publishing release #{version_number} on GitHub" + + publish_github_release( + repository: GITHUB_REPO, + name: version_number + ) + + create_backmerge_pr + + # At this point, an intermediate branch has been created by creating a backmerge PR to a hotfix or the next version release branch. + # This allows us to safely delete the `release/*` remote branch. + remove_branch_protection(repository: GITHUB_REPO, branch: current_branch) + Fastlane::Helper::GitHelper.delete_remote_branch_if_exists!(current_branch) + Fastlane::Helper::GitHelper.checkout_and_pull(DEFAULT_BRANCH) + Fastlane::Helper::GitHelper.delete_local_branch_if_exists!(current_branch) + end + + # @param branch_to_build [String] The branch to build. Defaults to the current git branch. + # + lane :trigger_release_build do |branch_to_build: git_branch| + buildkite_trigger_build( + buildkite_organization: 'automattic', + buildkite_pipeline: 'pocket-casts-android', + branch: branch_to_build, + pipeline_file: 'release-builds.yml' + ) + end + + # Builds and uploads a new build to Google Play (without releasing it) + # + # - Uses the current version to decide if this is a beta or production build + # - Builds the apps for external distribution + # - Uploads the builds to 'beta' or 'production' Play Store channel (but does not release it) + # - Creates draft Github release + # + # @param skip_confirm [Boolean] If true, avoids any interactive prompt + # @param skip_prechecks [Boolean] If true, skips android_build_preflight + # @param create_gh_release [Boolean] If true, creates a draft GitHub release + # + lane :build_and_upload_to_play_store do |skip_prechecks: false, skip_confirm: false, create_gh_release: false| + version = version_name_current + build_code = build_code_current + is_beta = beta_version?(version) + unless skip_prechecks + # Match branch names that begin with `release/` + ensure_git_branch(branch: '^release/') unless is_ci + + UI.important("Building version #{version_name_current} (#{build_code_current}) for upload to Google Play Console") + UI.user_error!("Terminating as requested. Don't forget to run the remainder of this automation manually.") unless skip_confirm || UI.confirm('Do you want to continue?') + + # Check local repo status + ensure_git_status_clean unless is_ci + + android_build_preflight + end + + release_assets = [] + + APPS.each do |app| + build_bundle(app: app, version: version, build_code: build_code) + + aab_artifact_path = aab_artifact_path(app, version) + UI.error("Unable to find a build artifact at #{aab_artifact_path}") unless File.exist? aab_artifact_path + + track = play_store_track(app: app, is_beta: is_beta) + upload_to_play_store( + **UPLOAD_TO_PLAY_STORE_COMMON_OPTIONS, + aab: aab_artifact_path, + track: track, + release_status: 'draft' + ) + release_assets << aab_artifact_path + + signed_apk_artifact_path = signed_apk_artifact_path(app, version) + download_universal_apk_from_google_play( + package_name: APP_PACKAGE_NAME, + version_code: version_code_for_app(app: app, version_code: build_code), + destination: signed_apk_artifact_path, + json_key: UPLOAD_TO_PLAY_STORE_JSON_KEY + ) + release_assets << signed_apk_artifact_path + end + + create_gh_release(version: version, prerelease: is_beta, release_assets: release_assets.compact) if create_gh_release + end + # Builds and bundles the given app # # @param version [String] The version to create @@ -572,7 +612,7 @@ platform :android do # private_lane :create_gh_release do |version:, prerelease: false, release_assets: []| create_github_release( - repository: GH_REPOSITORY, + repository: GITHUB_REPO, version: version, release_notes_file_path: EXTRACTED_RELEASE_NOTES_PATH, prerelease: prerelease, @@ -583,7 +623,7 @@ platform :android do lane :create_backmerge_pr do |version: release_version_current| create_release_backmerge_pull_request( - repository: GH_REPOSITORY, + repository: GITHUB_REPO, source_branch: "release/#{version}", default_branch: DEFAULT_BRANCH, labels: ['Releases'],