diff --git a/.buildkite/commands/build-prototype.sh b/.buildkite/commands/build-prototype.sh index 655cce15f..f86e4c407 100755 --- a/.buildkite/commands/build-prototype.sh +++ b/.buildkite/commands/build-prototype.sh @@ -9,5 +9,5 @@ install_cocoapods echo "--- :closed_lock_with_key: Installing Secrets" bundle exec fastlane run configure_apply -echo "--- :hammer_and_wrench: Build and Upload to App Center" -bundle exec fastlane build_and_upload_installable_build +echo "--- :hammer_and_wrench: Build and Upload to Firebase App Distribution" +bundle exec fastlane build_and_upload_prototype_build diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 5e4fb659f..12f53eac6 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -40,9 +40,9 @@ steps: queue: "linter" ################# - # Create Installable Build + # Prototype Build ################# - - label: "🛠 Installable Build" + - label: "🛠 Prototype Build" command: ".buildkite/commands/build-prototype.sh" plugins: [$CI_TOOLKIT_PLUGIN] if: "build.pull_request.id != null || build.pull_request.draft" diff --git a/Gemfile b/Gemfile index 227e97178..75b6e6a75 100644 --- a/Gemfile +++ b/Gemfile @@ -6,9 +6,9 @@ source 'https://rubygems.org' gem 'cocoapods', '~> 1.14' gem 'danger-dangermattic', '~> 1.0' gem 'fastlane', '~> 2' -gem 'fastlane-plugin-appcenter', '~> 2.1.2' +gem 'fastlane-plugin-firebase_app_distribution', '~> 0.10' gem 'fastlane-plugin-sentry', '~> 1.6' -gem 'fastlane-plugin-wpmreleasetoolkit', '~> 12.2' +gem 'fastlane-plugin-wpmreleasetoolkit', '~> 13.0' group :screenshots, optional: true do gem 'rmagick', '~> 3.2.0' diff --git a/Gemfile.lock b/Gemfile.lock index 485983558..17d2b1d3f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -205,10 +205,12 @@ GEM xcodeproj (>= 1.13.0, < 2.0.0) xcpretty (~> 0.4.0) xcpretty-travis-formatter (>= 0.0.3, < 2.0.0) - fastlane-plugin-appcenter (2.1.2) + fastlane-plugin-firebase_app_distribution (0.10.0) + google-apis-firebaseappdistribution_v1 (~> 0.3.0) + google-apis-firebaseappdistribution_v1alpha (~> 0.2.0) fastlane-plugin-sentry (1.22.0) os (~> 1.1, >= 1.1.4) - fastlane-plugin-wpmreleasetoolkit (12.4.0) + fastlane-plugin-wpmreleasetoolkit (13.0.0) activesupport (>= 6.1.7.1) buildkit (~> 1.5) chroma (= 0.2.0) @@ -245,6 +247,10 @@ GEM representable (~> 3.0) retriable (>= 2.0, < 4.a) rexml + google-apis-firebaseappdistribution_v1 (0.3.0) + google-apis-core (>= 0.11.0, < 2.a) + google-apis-firebaseappdistribution_v1alpha (0.2.0) + google-apis-core (>= 0.11.0, < 2.a) google-apis-iamcredentials_v1 (0.17.0) google-apis-core (>= 0.11.0, < 2.a) google-apis-playcustomapp_v1 (0.13.0) @@ -299,9 +305,9 @@ GEM naturally (2.2.1) netrc (0.11.0) nkf (0.2.0) - nokogiri (1.18.2-arm64-darwin) + nokogiri (1.18.4-arm64-darwin) racc (~> 1.4) - nokogiri (1.18.2-x86_64-linux-gnu) + nokogiri (1.18.4-x86_64-linux-gnu) racc (~> 1.4) octokit (6.1.1) faraday (>= 1, < 3) @@ -402,9 +408,9 @@ DEPENDENCIES cocoapods (~> 1.14) danger-dangermattic (~> 1.0) fastlane (~> 2) - fastlane-plugin-appcenter (~> 2.1.2) + fastlane-plugin-firebase_app_distribution (~> 0.10) fastlane-plugin-sentry (~> 1.6) - fastlane-plugin-wpmreleasetoolkit (~> 12.2) + fastlane-plugin-wpmreleasetoolkit (~> 13.0) rmagick (~> 3.2.0) BUNDLED WITH diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 8809290e0..a77e0c005 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -23,7 +23,9 @@ PROJECT_SLUG = 'simplenote-ios' GITHUB_REPO = "#{ORGANIZATION}/#{PROJECT_SLUG}".freeze BUILDKITE_ORGANIZATION = ORGANIZATION BUILDKITE_PIPELINE = PROJECT_SLUG -APPCENTER_OWNER_NAME = ORGANIZATION + +FIREBASE_APP_ID = '1:124902176124:ios:d21314b0300402801620f9' +FIREBASE_TESTERS_GROUP = 'simplenote-ios---prototype-builds' WORKSPACE = 'Simplenote.xcworkspace' @@ -105,24 +107,14 @@ platform :ios do ) end - ##################################################################################### - # build_and_upload_installable_build - # ----------------------------------------------------------------------------------- - # This lane builds the app and upload it for adhoc testing - # ----------------------------------------------------------------------------------- - # Usage: - # bundle exec fastlane build_and_upload_installable_build + # Build the app and upload it to Firebase App Distribution for adhoc testing # - # Example: - # bundle exec fastlane build_and_upload_installable_build - ##################################################################################### - desc 'Builds and uploads an installable build' - lane :build_and_upload_installable_build do + desc 'Builds and uploads a prototype build' + lane :build_and_upload_prototype_build do update_certs_and_profiles_enterprise - # Get the current build version, and update it if needed - build_number = generate_installable_build_number - apply_build_number(build_number) + pr_or_branch = pull_request_number&.then { |num| "PR ##{num}" } || ENV.fetch('BUILDKITE_BRANCH', nil) + build_number = ENV.fetch('BUILDKITE_BUILD_NUMBER', '0') gym( scheme: 'Simplenote', @@ -130,7 +122,9 @@ platform :ios do workspace: WORKSPACE, export_method: 'enterprise', clean: true, + xcargs: { VERSION_SHORT: pr_or_branch, VERSION_LONG: build_number }, output_directory: OUTPUT_DIRECTORY_PATH, + output_name: 'Simplenote Alpha', export_team_id: TEAM_ID_ENTERPRISE, export_options: { method: 'enterprise', @@ -141,16 +135,17 @@ platform :ios do } ) - File.rename(File.join(OUTPUT_DIRECTORY_PATH, 'Simplenote.ipa'), File.join(OUTPUT_DIRECTORY_PATH, 'Simplenote Alpha.ipa')) - - appcenter_upload( - api_token: EnvManager.get_required_env!('APPCENTER_API_TOKEN'), - owner_name: 'automattic', - owner_type: 'organization', - app_name: 'Simplenote-Installable-Builds', - file: File.join(OUTPUT_DIRECTORY_PATH, 'Simplenote Alpha.ipa'), - destinations: 'All-Users-of-Simplenote-Installable-Builds', - notify_testers: false + release_notes = <<~NOTES + Pull Request: ##{pull_request_number || 'N/A'} + Branch: `#{ENV.fetch('BUILDKITE_BRANCH', 'N/A')}` + Commit: #{ENV.fetch('BUILDKITE_COMMIT', 'N/A')[0...7]} + NOTES + + firebase_app_distribution( + app: FIREBASE_APP_ID, + service_credentials_json_data: EnvManager.get_required_env!('FIREBASE_APP_DISTRIBUTION_ACCOUNT_KEY'), + release_notes: release_notes, + groups: FIREBASE_TESTERS_GROUP ) sentry_upload_dsym( @@ -160,31 +155,16 @@ platform :ios do dsym_path: lane_context[SharedValues::DSYM_OUTPUT_PATH] ) - return if ENV['BUILDKITE_PULL_REQUEST'].nil? - - post_installable_build_pr_comment - end - - # Posts a comment on the current PR to inform where to download a given Installable Build that was just published to App Center. - # - # Use this only after `upload_to_app_center` as been called, as it announces how said App Center build can be installed. - # - # @called_by CI — especially, relies on `BUILDKITE_PULL_REQUEST` being defined - # - def post_installable_build_pr_comment - pr = ENV.fetch('BUILDKITE_PULL_REQUEST', nil) - - return if pr.nil? + next if pull_request_number.nil? + # Post PR Comment comment_body = prototype_build_details_comment( app_display_name: 'Simplenote Prototype Build', - app_center_org_name: APPCENTER_OWNER_NAME, fold: true ) - comment_on_pr( project: GITHUB_REPO, - pr_number: Integer(pr), + pr_number: pull_request_number, reuse_identifier: 'installable-build-link--Simplenote-Installable-Builds', body: comment_body ) @@ -544,6 +524,12 @@ end # Helper Lanes ######################################################################## +def pull_request_number + # Buildkite sets this env var to the PR number if on a PR, but to 'false' (and not nil) if not on a PR + pr_num = ENV.fetch('BUILDKITE_PULL_REQUEST', 'false') + pr_num == 'false' ? nil : Integer(pr_num) +end + def fastlane_directory __dir__ end @@ -676,31 +662,6 @@ def submit_accounts_hash(accounts_hash) UI.message("Accounts state after write: #{fetch_test_accounts_hash}") end -def apply_build_number(build_number) - versions = Xcodeproj::Config.new(File.new(VERSION_FILE_PATH)).to_hash - UI.message("Updating build version to #{build_number}") - versions['VERSION_LONG'] = build_number - new_config = Xcodeproj::Config.new(versions) - new_config.save_as(Pathname.new(VERSION_FILE_PATH)) -end - -def generate_installable_build_number - if ENV['BUILDKITE'] - commit = ENV.fetch('BUILDKITE_COMMIT', nil)[0, 7] - branch = ENV.fetch('BUILDKITE_BRANCH', nil) - pr_num = ENV.fetch('BUILDKITE_PULL_REQUEST', nil) - build = ENV.fetch('BUILDKITE_BUILD_ID', nil) - - pr_num == 'false' ? "#{branch}-#{commit}-#{build}" : "pr#{pr_num}-#{commit}-#{build}" - else - repo = Git.open(PROJECT_ROOT_FOLDER) - commit = repo.current_branch - branch = repo.revparse('HEAD')[0, 7] - - "#{branch}-#{commit}" - end -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 diff --git a/fastlane/env/project.env-example b/fastlane/env/project.env-example index 280df896d..371b75b57 100644 --- a/fastlane/env/project.env-example +++ b/fastlane/env/project.env-example @@ -1,8 +1,6 @@ INT_EXPORT_TEAM_ID= EXT_EXPORT_TEAM_ID= -APPCENTER_PUBLIC_ID= - FASTLANE_ITC_TEAM_ID= SENTRY_ORG_SLUG= diff --git a/fastlane/env/user.env-example b/fastlane/env/user.env-example index 254bd83be..d19f2fa68 100644 --- a/fastlane/env/user.env-example +++ b/fastlane/env/user.env-example @@ -1,3 +1,2 @@ GHHELPER_ACCESS= -APPCENTER_API_TOKEN= SENTRY_AUTH_TOKEN= diff --git a/fastlane/example.env b/fastlane/example.env index 4d561bbe6..22bffa10f 100644 --- a/fastlane/example.env +++ b/fastlane/example.env @@ -11,7 +11,6 @@ APP_STORE_CONNECT_API_KEY_KEY_ID= APP_STORE_CONNECT_API_KEY_ISSUER_ID= APP_STORE_CONNECT_API_KEY_KEY= -APPCENTER_API_TOKEN= SENTRY_AUTH_TOKEN= UI_TESTS_ACCOUNT_EMAIL=