diff --git a/.buildkite/commands/build-tvos-app-store.sh b/.buildkite/commands/build-tvos-app-store.sh index 3860cab0f4..5b4cd817fd 100755 --- a/.buildkite/commands/build-tvos-app-store.sh +++ b/.buildkite/commands/build-tvos-app-store.sh @@ -12,5 +12,6 @@ echo "--- :closed_lock_with_key: Installing Secrets" bundle exec fastlane run configure_apply echo "--- :hammer_and_wrench: Building" -# The `0.` prefix keeps CI-driven builds lexicographically below any real release build code. +# CI-driven tvOS uploads use a low 0.x build number. App Store Connect may +# reject these after a release build already exists for the same version. bundle exec fastlane build_app_store_connect_tvos "build_number:0.$BUILDKITE_BUILD_NUMBER" diff --git a/.buildkite/commands/release-build.sh b/.buildkite/commands/release-build.sh index 8753e19fc3..b13e3d131c 100755 --- a/.buildkite/commands/release-build.sh +++ b/.buildkite/commands/release-build.sh @@ -2,6 +2,13 @@ # Ensure we get the latest commit of the `release/*` branch, especially to get last version bump commit before building the release RELEASE_VERSION="${1:?RELEASE_VERSION parameter missing}" +RELEASE_PLATFORM="${2:-${RELEASE_PLATFORM:-}}" + +if [[ -z "$RELEASE_PLATFORM" ]]; then + echo "RELEASE_PLATFORM parameter missing. Expected 'ios' or 'tvos'." >&2 + exit 1 +fi + "$(dirname "${BASH_SOURCE[0]}")/checkout-release-branch.sh" "$RELEASE_VERSION" "$(dirname "${BASH_SOURCE[0]}")/shared_setup.sh" @@ -9,5 +16,17 @@ RELEASE_VERSION="${1:?RELEASE_VERSION parameter missing}" echo "--- :closed_lock_with_key: Installing Secrets" bundle exec fastlane run configure_apply -echo "--- :hammer_and_wrench: Building" -bundle exec fastlane build_app_store_connect +case "$RELEASE_PLATFORM" in + ios) + echo "--- :hammer_and_wrench: Building iOS" + bundle exec fastlane build_app_store_connect + ;; + tvos) + echo "--- :hammer_and_wrench: Building tvOS" + bundle exec fastlane build_app_store_connect_tvos + ;; + *) + echo "Unsupported RELEASE_PLATFORM: $RELEASE_PLATFORM. Expected 'ios' or 'tvos'." >&2 + exit 1 + ;; +esac diff --git a/.buildkite/commands/release-upload.sh b/.buildkite/commands/release-upload.sh index 7a663e2d9a..ff955852f3 100755 --- a/.buildkite/commands/release-upload.sh +++ b/.buildkite/commands/release-upload.sh @@ -2,17 +2,65 @@ # Ensure we get the latest commit of the `release/*` branch, especially to get last version bump commit before publishing the GitHub Release and creating the git tag RELEASE_VERSION="${1:?RELEASE_VERSION parameter missing}" -"$(dirname "${BASH_SOURCE[0]}")/checkout-release-branch.sh" "$RELEASE_VERSION" BETA_RELEASE=${2:-true} # use second call param, default to true for safety +RELEASE_PLATFORM="${3:-${RELEASE_PLATFORM:-}}" +NOTIFY_SLACK="${4:-${NOTIFY_SLACK:-}}" +CREATE_GITHUB_RELEASE="${5:-${CREATE_GITHUB_RELEASE:-}}" + +if [[ -z "$RELEASE_PLATFORM" ]]; then + echo "RELEASE_PLATFORM parameter missing. Expected 'ios' or 'tvos'." >&2 + exit 1 +fi + +case "$RELEASE_PLATFORM" in + ios) + PLATFORM_NAME="iOS" + IPA_PATH="artifacts/pocket-casts.ipa" + DSYM_PATH="artifacts/pocket-casts.app.dSYM.zip" + ARCHIVE_ZIP_PATH="artifacts/pocket-casts.xcarchive.zip" + SENTRY_ANNOTATION_CONTEXT="sentry-failure-ios" + TESTFLIGHT_LANE="upload_app_store_connect_build_to_testflight" + ;; + tvos) + PLATFORM_NAME="tvOS" + IPA_PATH="artifacts/pocket-casts-tvos.ipa" + DSYM_PATH="artifacts/pocket-casts-tvos.app.dSYM.zip" + ARCHIVE_ZIP_PATH="artifacts/pocket-casts-tvos.xcarchive.zip" + SENTRY_ANNOTATION_CONTEXT="sentry-failure-tvos" + TESTFLIGHT_LANE="upload_app_store_connect_build_to_testflight_tvos" + ;; + *) + echo "Unsupported RELEASE_PLATFORM: $RELEASE_PLATFORM. Expected 'ios' or 'tvos'." >&2 + exit 1 + ;; +esac + +if [[ -z "$NOTIFY_SLACK" ]]; then + if [[ "$RELEASE_PLATFORM" == "ios" ]]; then + NOTIFY_SLACK="true" + else + NOTIFY_SLACK="false" + fi +fi + +if [[ -z "$CREATE_GITHUB_RELEASE" ]]; then + if [[ "$RELEASE_PLATFORM" == "ios" ]]; then + CREATE_GITHUB_RELEASE="true" + else + CREATE_GITHUB_RELEASE="false" + fi +fi -echo "Running $0 with BETA_RELEASE = $BETA_RELEASE..." +echo "Running $0 with BETA_RELEASE = $BETA_RELEASE, RELEASE_PLATFORM = $RELEASE_PLATFORM, NOTIFY_SLACK = $NOTIFY_SLACK, CREATE_GITHUB_RELEASE = $CREATE_GITHUB_RELEASE..." + +"$(dirname "${BASH_SOURCE[0]}")/checkout-release-branch.sh" "$RELEASE_VERSION" echo "--- :arrow_down: Downloading Artifacts" -ARTIFACTS_DIR='artifacts' # Defined in Fastlane, see ARTIFACTS_FOLDER -STEP=testflight_build -buildkite-agent artifact download "$ARTIFACTS_DIR/*.ipa" . --step $STEP -buildkite-agent artifact download "$ARTIFACTS_DIR/*.zip" . --step $STEP +STEP=release_build +buildkite-agent artifact download "$IPA_PATH" . --step "$STEP" +buildkite-agent artifact download "$DSYM_PATH" . --step "$STEP" +buildkite-agent artifact download "$ARCHIVE_ZIP_PATH" . --step "$STEP" echo "--- :rubygems: Setting up Gems" install_gems @@ -20,19 +68,34 @@ install_gems echo "--- :closed_lock_with_key: Installing Secrets" bundle exec fastlane run configure_apply -echo "--- :testflight: Uploading to TestFlight" -bundle exec fastlane upload_app_store_connect_build_to_testflight +echo "--- :github: Updating GitHub Release" +bundle exec fastlane create_release_on_github beta_release:"$BETA_RELEASE" archive_zip_path:"$ARCHIVE_ZIP_PATH" notify_slack:false create_release:"$CREATE_GITHUB_RELEASE" -echo "--- :arrow_up: Uploading dSYM to Sentry" -set +e -bundle exec fastlane symbols_upload -SENTRY_UPLOAD_STATUS=$? -set -e +upload_symbols() { + local platform="$1" + local dsym_path="$2" + local annotation_context="$3" -if [[ $SENTRY_UPLOAD_STATUS -ne 0 ]]; then - echo "^^^ +++ Failed to upload dSYM to Sentry! Make sure to download dSYM from the build step artifacts and upload manually." - buildkite-agent annotate --style error --context sentry-failure 'Failed to upload dSYM to Sentry! Make sure to download dSYM from the build step artifacts and upload manually.' -fi + echo "--- :arrow_up: Uploading $platform dSYM to Sentry" + set +e + bundle exec fastlane symbols_upload "dsym_path:$dsym_path" + local sentry_upload_status=$? + set -e + + if [[ $sentry_upload_status -ne 0 ]]; then + echo "^^^ +++ Failed to upload $platform dSYM to Sentry! Make sure to download dSYM from the build step artifacts and upload manually." + buildkite-agent annotate --style error --context "$annotation_context" "Failed to upload $platform dSYM to Sentry! Make sure to download dSYM from the build step artifacts and upload manually." + fi +} -echo "--- :github: Creating GitHub Release" -bundle exec fastlane create_release_on_github beta_release:"$BETA_RELEASE" +upload_symbols "$PLATFORM_NAME" "$DSYM_PATH" "$SENTRY_ANNOTATION_CONTEXT" + +echo "--- :testflight: Uploading $PLATFORM_NAME to TestFlight" +bundle exec fastlane "$TESTFLIGHT_LANE" ipa_path:"$IPA_PATH" + +if [[ "$NOTIFY_SLACK" == "true" ]]; then + echo "--- :slack: Notifying Slack" + bundle exec fastlane notify_release_on_slack beta_release:"$BETA_RELEASE" +else + echo "--- :slack: Skipping Slack notification" +fi diff --git a/.buildkite/release-builds.yml b/.buildkite/release-builds.yml index 46d170f010..77e9175594 100644 --- a/.buildkite/release-builds.yml +++ b/.buildkite/release-builds.yml @@ -12,9 +12,9 @@ env: steps: - - label: "🛠 Release Build (App Store Connect)" - key: testflight_build - command: .buildkite/commands/release-build.sh "${RELEASE_VERSION}" + - label: "🛠 Release Build (${RELEASE_PLATFORM})" + key: release_build + command: .buildkite/commands/release-build.sh "${RELEASE_VERSION}" "${RELEASE_PLATFORM}" priority: 1 plugins: [$CI_TOOLKIT] artifact_paths: @@ -23,9 +23,9 @@ steps: notify: - slack: "#build-and-ship" - - label: ":testflight: Release Upload (TestFlight, Sentry, GitHub)" - depends_on: testflight_build - command: .buildkite/commands/release-upload.sh "${RELEASE_VERSION}" "${BETA_RELEASE}" + - label: ":testflight: Release Upload (${RELEASE_PLATFORM})" + depends_on: release_build + command: .buildkite/commands/release-upload.sh "${RELEASE_VERSION}" "${BETA_RELEASE}" "${RELEASE_PLATFORM}" "${NOTIFY_SLACK}" "${CREATE_GITHUB_RELEASE}" priority: 1 plugins: [$CI_TOOLKIT] notify: diff --git a/Gemfile b/Gemfile index 6ffe25cc44..8767cef15e 100644 --- a/Gemfile +++ b/Gemfile @@ -7,7 +7,7 @@ gem 'danger-dangermattic', '~> 1.3' gem 'fastlane', '~> 2.236' gem 'fastlane-plugin-firebase_app_distribution', '~> 1.0' gem 'fastlane-plugin-sentry', '~> 2.5' -gem 'fastlane-plugin-wpmreleasetoolkit', '~> 14.7' +gem 'fastlane-plugin-wpmreleasetoolkit', '~> 14.9.0' # To avoid errors like: # # SSL_connect returned=1 errno=0 peeraddr=3.5.132.155:443 state=error: certificate verify failed (unable to get certificate CRL) diff --git a/Gemfile.lock b/Gemfile.lock index b7079953d3..0cf3e9c809 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -169,7 +169,7 @@ GEM google-apis-firebaseappdistribution_v1alpha (>= 0.12.0) fastlane-plugin-sentry (2.5.8) os (~> 1.1, >= 1.1.4) - fastlane-plugin-wpmreleasetoolkit (14.7.0) + fastlane-plugin-wpmreleasetoolkit (14.9.0) buildkit (~> 1.5) chroma (= 0.2.0) diffy (~> 3.3) @@ -380,7 +380,7 @@ DEPENDENCIES fastlane (~> 2.236) fastlane-plugin-firebase_app_distribution (~> 1.0) fastlane-plugin-sentry (~> 2.5) - fastlane-plugin-wpmreleasetoolkit (~> 14.7) + fastlane-plugin-wpmreleasetoolkit (~> 14.9.0) openssl (~> 4.0) rake (>= 12.0, < 14.0) rubocop (~> 1.88) diff --git a/Pocket Casts TV App/Config/PocketCastsTV.base.xcconfig b/Pocket Casts TV App/Config/PocketCastsTV.base.xcconfig index 95b0139f43..8842227ae6 100644 --- a/Pocket Casts TV App/Config/PocketCastsTV.base.xcconfig +++ b/Pocket Casts TV App/Config/PocketCastsTV.base.xcconfig @@ -1,8 +1,5 @@ #include "../../config/PocketCasts.base.xcconfig" -// tvOS tracks its own marketing version — still early-days, so we don't piggyback on the iOS `VERSION_SHORT` release automation. -MARKETING_VERSION = 0.1 - SDKROOT = appletvos TVOS_DEPLOYMENT_TARGET = 26.0 TARGETED_DEVICE_FAMILY = 3 diff --git a/fastlane/Fastfile b/fastlane/Fastfile index d28eaa7692..d06429e9b3 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -289,7 +289,6 @@ platform :ios do # - Cuts a new release branch, Bumps the version # - Extracts the Release Notes # - Generates `.strings` files from code then merges the other, manually-maintained `.strings` files with it - # - Triggers the build of the first beta on CI # - Open backmerge PR # - Enables the GitHub branch protection for the new branch # - Move all still-opened PRs targeting current milestone to the next one and Freezes the GitHub milestone @@ -356,7 +355,6 @@ platform :ios do push_to_git_remote(set_upstream: true, tags: false) - trigger_beta_build(branch_to_build: release_branch_name) create_backmerge_pr # Copy the branch protection settings from the default branch to the new release branch @@ -368,7 +366,7 @@ platform :ios do update_milestone end - # Creates a new beta by bumping the app version appropriately then triggering a beta build on CI + # Creates a new beta by bumping the app version appropriately. # # @param base_version [String] If set, bases the beta on the specified version and `release/` branch # instead of using the current app version. Useful e.g. for triggering betas on hotfixes. @@ -416,16 +414,18 @@ platform :ios do push_to_git_remote(tags: false) - trigger_beta_build(branch_to_build: release_branch_name) create_backmerge_pr end - # Finalizes a release at the end of a sprint to submit to the App Store + # Finalizes release bookkeeping before separate CI jobs upload the final TestFlight builds. # - # - Updates store metadata + # This lane does not submit builds to App Store Review. Submission remains a + # manual App Store Connect/Releases v2 step. It also does not build or upload + # app binaries; Releases V2 starts those per-platform tasks separately. + # + # - Refreshes and lints localized strings and App Store Connect metadata # - Bumps final version number # - Removes branch protection and close milestone - # - Triggers the final release on CI # # @param skip_confirm [Boolean] If true, avoids any interactive prompt (default: false) # @@ -459,9 +459,6 @@ platform :ios do set_milestone_frozen_marker(repository: GITHUB_REPO, milestone: release_version_current, freeze: false) close_milestone(repository: GITHUB_REPO, milestone: release_version_current) - # Start the build - - trigger_release_build(branch_to_build: release_branch_name) create_backmerge_pr end @@ -579,7 +576,7 @@ platform :ios do push_to_git_remote(set_upstream: true, tags: false) end - # Finalizes a hotfix, by triggering a release build on CI + # Finalizes a hotfix before separate CI jobs upload the final TestFlight builds. # lane :finalize_hotfix_release do |skip_confirm: false| # Verify that the current branch is a release branch. Notice that `ensure_git_branch` expects a RegEx parameter @@ -588,10 +585,9 @@ platform :ios do # Verify that there's nothing in progress in the working copy ensure_git_status_clean - UI.important("Triggering hotfix build for version: #{release_version_current}") + UI.important("Finalizing hotfix for version: #{release_version_current}") UI.user_error!('Aborted by user request') unless skip_confirm || UI.confirm('Do you want to continue?') push_to_git_remote(tags: false) - trigger_release_build(branch_to_build: "release/#{release_version_current}") create_backmerge_pr begin @@ -603,18 +599,30 @@ platform :ios do # Triggers a beta build on CI # + # Kept for manual/ad-hoc triggering. Releases V2 starts release builds directly + # through `release-builds.yml` with platform-specific environment variables. + # # @param branch_to_build [String] The name of the branch we want the CI to build, e.g. `release/19.3` + # @param platform [String] The platform build to trigger, either `ios` or `tvos` + # @param notify_slack [Boolean, nil] Optional Slack notification override. nil keeps the platform default: true for iOS, false for tvOS. + # @param create_release [Boolean, nil] Optional GitHub Release creation override. nil keeps the platform default: true for iOS, false for tvOS. # - lane :trigger_beta_build do |branch_to_build:| - trigger_buildkite_release_build(branch: branch_to_build, beta: true) + lane :trigger_beta_build do |branch_to_build:, platform: 'ios', notify_slack: nil, create_release: nil| + trigger_buildkite_release_build(branch: branch_to_build, beta: true, platform: platform, notify_slack: notify_slack, create_release: create_release) end # Triggers a stable release build on CI # + # Kept for manual/ad-hoc triggering. Releases V2 starts release builds directly + # through `release-builds.yml` with platform-specific environment variables. + # # @param branch_to_build [String] The name of the branch we want the CI to build, e.g. `release/19.3` + # @param platform [String] The platform build to trigger, either `ios` or `tvos` + # @param notify_slack [Boolean, nil] Optional Slack notification override. nil keeps the platform default: true for iOS, false for tvOS. + # @param create_release [Boolean, nil] Optional GitHub Release creation override. nil keeps the platform default: true for iOS, false for tvOS. # - lane :trigger_release_build do |branch_to_build:| - trigger_buildkite_release_build(branch: branch_to_build, beta: false) + lane :trigger_release_build do |branch_to_build:, platform: 'ios', notify_slack: nil, create_release: nil| + trigger_buildkite_release_build(branch: branch_to_build, beta: false, platform: platform, notify_slack: notify_slack, create_release: create_release) end # Builds the app binary for distribution to App Store Connect @@ -838,14 +846,19 @@ platform :ios do # # @param beta_release [Boolean] If true, the GitHub Release is for a beta and will be marked as prerelease and published immediately. # If false, the GitHub Release is for a final build and will not be marked as prerelease but will be created as Draft (to be manually published only once approved by Apple) - # @param archive_zip_path [String] Path to the `.xcarchive.zip` file to attach as an asset to the created GitHub Release + # @param archive_zip_path [String] Path to the `.xcarchive.zip` file to attach as an asset to the created GitHub Release. + # @param notify_slack [Boolean] If true, sends the release notification to Slack. + # @param create_release [Boolean] If true, creates the GitHub Release when it does not already exist. # - lane :create_release_on_github do |beta_release: true, archive_zip_path: APP_STORE_CONNECT_XCARCHIVE_ZIP_PATH| - require_env_vars!('GITHUB_TOKEN', 'SLACK_WEBHOOK') + lane :create_release_on_github do |beta_release: true, archive_zip_path: APP_STORE_CONNECT_XCARCHIVE_ZIP_PATH, notify_slack: true, create_release: true| + beta_release = boolean_option(beta_release, default: true) + notify_slack = boolean_option(notify_slack, default: true) + create_release = boolean_option(create_release, default: true) - app_version = release_version_current - build_version = build_code_current - version = beta_release ? build_version : app_version + require_env_vars!('GITHUB_TOKEN') + + version = github_release_version(beta_release: beta_release) + UI.user_error!("Can't find file #{archive_zip_path}!") unless File.file?(archive_zip_path.to_s) changelog = extract_release_notes_for_version( version: release_version_current, @@ -853,22 +866,55 @@ platform :ios do ) changelog = '_`CHANGELOG.md` was empty for this version._' if changelog.empty? - UI.message("Creating #{version} release on GitHub...") - set_github_release( - repository_name: GITHUB_REPO, - api_token: get_required_env!('GITHUB_TOKEN'), - name: version, - tag_name: version, - description: changelog, - commitish: Git.open(PROJECT_ROOT_FOLDER).log.first.sha, - upload_assets: [archive_zip_path.to_s], - is_draft: !beta_release, - is_prerelease: beta_release + api_token = get_required_env!('GITHUB_TOKEN') + release = get_github_release(url: GITHUB_REPO, version: version, api_token: api_token) + + if release.nil? && create_release + UI.message("Creating #{version} release on GitHub...") + release = set_github_release( + repository_name: GITHUB_REPO, + api_token: api_token, + name: version, + tag_name: version, + description: changelog, + commitish: Git.open(PROJECT_ROOT_FOLDER).log.first.sha, + is_draft: !beta_release, + is_prerelease: beta_release + ) + release ||= get_github_release(url: GITHUB_REPO, version: version, api_token: api_token) + end + + UI.user_error!("GitHub release #{version} does not exist yet. Run the iOS release upload first, then retry this upload step.") unless release && release['upload_url'] + + upload_github_release_assets( + repository: GITHUB_REPO, + version: version, + release_assets: [archive_zip_path], + replace_existing: true, + github_token: api_token ) + if notify_slack + notify_release_on_slack(beta_release: beta_release) + else + UI.message('Skipping Slack notification.') + end + end + + # Sends the release notification to Slack. + # + # Typically called after the build has been uploaded to TestFlight. + # + # @param beta_release [Boolean] If true, sends a beta notification. If false, sends a final/hotfix notification. + # + lane :notify_release_on_slack do |beta_release: true| + beta_release = boolean_option(beta_release, default: true) + + require_env_vars!('SLACK_WEBHOOK') + UI.message('Sending message to Slack...') slack( - pretext: slack_message(version: app_version, build_number: build_version, is_beta: beta_release), + pretext: slack_message(version: release_version_current, build_number: build_code_current, is_beta: beta_release), default_payloads: [], slack_url: get_required_env!('SLACK_WEBHOOK'), fail_on_error: false @@ -1132,22 +1178,18 @@ platform :ios do # @param with_screenshots [Boolean] If true, will also upload the latest screenshot files to ASC (default: false) # lane :update_metadata_on_app_store_connect do |with_screenshots: false| - # Skip screenshots by default. The naming is "with" to make it clear that - # callers need to opt-in to adding screenshots. The naming of the deliver - # (upload_to_app_store) parameter, on the other hand, uses the skip verb. - skip_screenshots = with_screenshots == false + upload_metadata_to_app_store_connect(platform: 'ios', with_screenshots: with_screenshots) + end - upload_to_app_store( - app_identifier: APP_BUNDLE_IDENTIFIER_APP_STORE, - app_version: release_version_current, - skip_binary_upload: true, - screenshots_path: File.join(FASTLANE_FOLDER, 'screenshots'), - skip_screenshots: skip_screenshots, - overwrite_screenshots: true, # won't have effect if `skip_screenshots` is true - phased_release: true, - precheck_include_in_app_purchases: false, - api_key: app_store_connect_api_key - ) + # Upload the localized tvOS metadata (from `fastlane/metadata/`) to App Store Connect. + # + # The tvOS app currently reuses iOS release notes and metadata. Screenshots stay opt-in; + # callers should only use `with_screenshots:true` once tvOS screenshots are present. + # + # @param with_screenshots [Boolean] If true, will also upload the latest screenshot files to ASC (default: false) + # + lane :update_metadata_on_app_store_connect_tvos do |with_screenshots: false| + upload_metadata_to_app_store_connect(platform: 'appletvos', with_screenshots: with_screenshots) end # Generates a HTML containing the libraries acknowledgments. @@ -1286,18 +1328,40 @@ platform :ios do "release/#{release_version_current}" end + def github_release_version(beta_release:) + beta_release ? build_code_current : release_version_current + end + + def boolean_option(value, default:) + return value if [true, false].include?(value) + return default if value.nil? + + value.to_s == 'true' + end + # Kicks off a Buildkite build using the `release-builds.yml` pipeline # # @param branch [String] The git branch on which to trigger the CI build on # @param beta [Boolean] If true, build a beta; if false, build a final release + # @param platform [String] The platform build to trigger, either `ios` or `tvos` + # @param notify_slack [Boolean, nil] Optional Slack notification override. nil keeps the platform default: true for iOS, false for tvOS. + # @param create_release [Boolean, nil] Optional GitHub Release creation override. nil keeps the platform default: true for iOS, false for tvOS. # @return [String] The URL of the build that has been triggered # - def trigger_buildkite_release_build(branch:, beta:) + def trigger_buildkite_release_build(branch:, beta:, platform: 'ios', notify_slack: nil, create_release: nil) + platform = platform.to_s.downcase + UI.user_error!("Unsupported release platform '#{platform}'. Expected 'ios' or 'tvos'.") unless %w[ios tvos].include?(platform) + notify_slack = boolean_option(notify_slack, default: platform == 'ios') + create_release = boolean_option(create_release, default: platform == 'ios') + pipeline_args = { pipeline_file: 'release-builds.yml', environment: { RELEASE_VERSION: release_version_current, - BETA_RELEASE: beta + BETA_RELEASE: beta, + RELEASE_PLATFORM: platform, + NOTIFY_SLACK: notify_slack, + CREATE_GITHUB_RELEASE: create_release } } if is_ci? @@ -1313,6 +1377,31 @@ platform :ios do end end + # Upload localized App Store Connect metadata for a specific App Store platform. + # + # @param platform [String] Fastlane deliver platform, such as `ios` or `appletvos` + # @param with_screenshots [Boolean] If true, will also upload the latest screenshot files to ASC + # + def upload_metadata_to_app_store_connect(platform:, with_screenshots:) + # Skip screenshots by default. The naming is "with" to make it clear that + # callers need to opt-in to adding screenshots. The naming of the deliver + # (upload_to_app_store) parameter, on the other hand, uses the skip verb. + skip_screenshots = with_screenshots == false + + upload_to_app_store( + app_identifier: APP_BUNDLE_IDENTIFIER_APP_STORE, + app_version: release_version_current, + platform: platform, + skip_binary_upload: true, + screenshots_path: File.join(FASTLANE_FOLDER, 'screenshots'), + skip_screenshots: skip_screenshots, + overwrite_screenshots: true, # won't have effect if `skip_screenshots` is true + phased_release: true, + precheck_include_in_app_purchases: false, + api_key: app_store_connect_api_key + ) + end + # Update the milestone of still-open PRs # # - Update the milestone of all still-open PRs that were assigned the milestone of the version being code-frozen, diff --git a/podcasts.xcodeproj/project.pbxproj b/podcasts.xcodeproj/project.pbxproj index 850f5449a5..f03d89996b 100644 --- a/podcasts.xcodeproj/project.pbxproj +++ b/podcasts.xcodeproj/project.pbxproj @@ -9961,7 +9961,6 @@ "@executable_path/Frameworks", ); LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MARKETING_VERSION = 0.1; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; SDKROOT = appletvos; @@ -10014,7 +10013,6 @@ "@executable_path/Frameworks", ); LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MARKETING_VERSION = 0.1; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = appletvos; @@ -10067,7 +10065,6 @@ "@executable_path/Frameworks", ); LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MARKETING_VERSION = 0.1; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = appletvos; @@ -10120,7 +10117,6 @@ "@executable_path/Frameworks", ); LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MARKETING_VERSION = 0.1; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = appletvos;