[match] Imported tvOS provisioning profile generated name does not match the one expected when retrieving profiles for building the tvOS app
New Issue Checklist
- [X] Updated fastlane to the latest version
- [X] I read the Contribution Guidelines
- [X] I read docs.fastlane.tools
- [X] I searched for existing GitHub issues
Issue Description
When importing the main tvOS app provisioning profile to bitbucket (using fastlane match command), the profile generated name does not contain the usual _tvOS suffix despite providing the parameter platform tvos. Hence, when building the app, match looks for a profile with the _tvOS suffix and does not find it. Moreover, the iOS app provisioning profile gets replaced by the tvOS app one.
Generated name for the tvOS app: AppStore_lu.<bundleID>.mobileprovision
Name expected by match when building the tvOS app: AppStore_lu.<bundleID>_tvos.mobileprovision
Full error message:
[09:40:03]: No matching provisioning profiles found for 'AppStore_lu.<bundleID>_tvos.mobileprovision'
[09:40:03]: A new one cannot be created because you enabled `readonly`
[09:40:03]: Provisioning profiles in your repo for type `appstore`:
[09:40:03]: - 'AppStore_lu.<bundleID>.notificationservice.mobileprovision'
[09:40:03]: - 'AppStore_lu.<bundleID>.tvtopshelf.mobileprovision'
[09:40:03]: - 'AppStore_lu.<bundleID>.mobileprovision'
Several notes:
- When using
match updatewith other developer accounts I have admin access to, the main tvOS app provisioning profile name generated by match contains the_tvOSsuffix. The issue only occurs when importing profiles usingmatch import. - The
_tvOSsuffix is also missing in the TV Top Shelp tvOS app extension provisioning profile generated name (should be 'AppStore_lu.<bundleID>.tvtopshelf_tvOS.mobileprovision') - Note sure I can safely share the provisioning profiles here so I don't but they are indeed tvOS platform profiles
Command executed
bundle exec fastlane match import --type appstore --skip_provisioning_profiles true --clone_branch_directly true --git_branch XXXXXXXX --team_id XXXXXXXX --app_identifier XXXXXXXX --platform tvos
Complete output when running fastlane, including the stack trace and command used
[✔] 🚀 Fastfile:77: warning: already initialized constant Spaceship::ConnectAPI::App::ESSENTIAL_INCLUDES /Users/aureliencolas/.rubies/ruby-3.2.1/lib/ruby/gems/3.2.0/gems/fastlane-2.220.0/spaceship/lib/spaceship/connect_api/models/app.rb:61: warning: previous definition of ESSENTIAL_INCLUDES was here [09:39:56]: ------------------------------ [09:39:56]: --- Step: default_platform --- [09:39:56]: ------------------------------ Available session is not valid anymore. Continuing with normal login. [09:40:00]: Driving the lane 'ios deploy_app' 🚀 [09:40:00]: ------------------- [09:40:00]: --- Step: match --- [09:40:00]: ------------------- [09:40:00]: Successfully loaded '/Users/aureliencolas/Documents/netgem/repos/videofutur-ios-swift/fastlane/Matchfile' 📄+----------------------------------------------------------+ | Detected Values from './fastlane/Matchfile' | +--------------+-------------------------------------------+ | git_url | [email protected]:netgem/ios-fastlane.git | | storage_mode | git | | type | appstore | +--------------+-------------------------------------------+
+------------------------------------------------------------------------------------+ | Summary for match 2.220.0 | +----------------------------------------+-------------------------------------------+ | type | appstore | | git_branch | XXXXXXXX | | clone_branch_directly | true | | app_identifier | ["XXXXXXXX"] | | platform | tvos | | readonly | true | | generate_apple_certs | true | | skip_provisioning_profiles | false | | username | XXXXXXXX | | storage_mode | git | | git_url | [email protected]:xxxxxxxxx.git | | shallow_clone | false | | skip_google_cloud_account_confirmation | false | | s3_skip_encryption | false | | gitlab_host | https://gitlab.com | | keychain_name | login.keychain | | force | false | | force_for_new_devices | false | | include_mac_in_profiles | false | | include_all_certificates | false | | force_for_new_certificates | false | | skip_confirmation | false | | safe_remove_certs | false | | skip_docs | false | | derive_catalyst_app_identifier | false | | fail_on_name_taken | false | | skip_certificate_matching | false | | skip_set_partition_list | false | | verbose | false | +----------------------------------------+-------------------------------------------+
[09:40:00]: Cloning remote git repo... [09:40:03]: Checking out branch XXXXXXXX... [09:40:03]: 🔓 Successfully decrypted certificates repo [09:40:03]: Installing certificate...
+-------------------------------------------------------------------------------------+ | Installed Certificate | +-------------------+-----------------------------------------------------------------+ | User ID | XXXXXXXX | | Common Name | iPhone Distribution: POST Luxembourg Etabl. Public (XXXXXXXX) | | Organisation Unit | XXXXXXXX | | Organisation | POST Luxembourg Etabl. Public | | Country | LU | | Start Datetime | 2023-08-07 14:29:30 UTC | | End Datetime | 2024-08-06 14:29:29 UTC | +-------------------+-----------------------------------------------------------------+
[09:40:03]: No matching provisioning profiles found for 'AppStore_lu.<bundleID>_tvos.mobileprovision' [09:40:03]: A new one cannot be created because you enabled
readonly[09:40:03]: Provisioning profiles in your repo for typeappstore: [09:40:03]: - 'AppStore_lu.<bundleID>.notificationservice.mobileprovision' [09:40:03]: - 'AppStore_lu.<bundleID>.tvtopshelf.mobileprovision' [09:40:03]: - 'AppStore_lu.<bundleID>.mobileprovision' [09:40:03]: If you are certain that a profile should exist, double-check the recent changes to your match repository +-----------------------------------+ | Lane Context | +------------------+----------------+ | DEFAULT_PLATFORM | ios | | PLATFORM_NAME | ios | | LANE_NAME | ios deploy_app | +------------------+----------------+ [09:40:03]: No matching provisioning profiles found and cannot create a new one because you enabledreadonly. Check the output above for more information.+---------------------------------------+ | fastlane summary | +------+------------------+-------------+ | Step | Action | Time (in s) | +------+------------------+-------------+ | 1 | default_platform | 0 | | 💥 | match | 3 | +------+------------------+-------------+
[09:40:03]: fastlane finished with errors
[!] No matching provisioning profiles found and cannot create a new one because you enabled
readonly. Check the output above for more information.
Environment
🚫 fastlane environment 🚫
Stack
Key Value OS 14.5 Ruby 3.2.1 Bundler? true Git git version 2.39.3 (Apple Git-146) Installation Source ~/.rubies/ruby-3.2.1/bin/fastlane Host macOS 14.5 (23F79) Ruby Lib Dir ~/.rubies/ruby-3.2.1/lib OpenSSL Version OpenSSL 1.1.1t 7 Feb 2023 Is contained false Is homebrew false Is installed via Fabric.app false Xcode Path /Applications/Xcode.app/Contents/Developer/ Xcode Version 15.4 Swift Version 5.10 System Locale
Error No Locale with UTF8 found 🚫 fastlane files:
`./Fastfile`
# This file contains the fastlane.tools configuration # You can find the documentation at https://docs.fastlane.tools # # For a list of all available actions, check out # # https://docs.fastlane.tools/actions # # For a list of all available plugins, check out # # https://docs.fastlane.tools/plugins/available-plugins # # Uncomment the line if you want fastlane to automatically update itself # update_fastlane # Launch a lane with: # bundle exec fastlane <lane> all_configs = [ ] custom_configs = [ ] teams_config = { } match_verbose = false require "spaceship" Spaceship::ConnectAPI::App.const_set('ESSENTIAL_INCLUDES', 'appStoreVersions') default_platform(:ios) # IMPORTANT: Increase the default timeout to 30s as the packages dependencies may take much longer to resolve than the default timeout (which could make the build fail) ENV['FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT'] = "30" def build(scheme, flavor, build_number, platform) UI.message "Building #{flavor} #{platform} ##{build_number}" output_name = "#{flavor}.ipa" output_directory = "./fastlane/builds/#{build_number}/#{platform}" build_app(scheme: scheme, output_directory: output_directory, output_name: output_name, clean: true, silent: false, xcargs: "-allowProvisioningUpdates") return "#{output_directory}/#{output_name}" end def to_testflight(ipa, team_name) UI.message "Uploading #{ipa} to the App Store with team: #{team_name}" # TODO: provide a "changelog" upload_to_testflight(ipa: ipa, team_name: team_name, skip_waiting_for_build_processing: true) end def check_valid_scheme(scheme) schemes = Xcodeproj::Project.schemes('../videofutur/videofutur.xcodeproj') valid = schemes.include? scheme if !valid UI.error "Invalid schem <#{scheme}>" UI.error "Valid schemes: #{schemes.join(", ")}" end return valid end # Gets the bundle identifier for the given scheme def getSchemeInfo(scheme) project = Xcodeproj::Project.open('../videofutur/videofutur.xcodeproj') target = project.native_targets.find { |target| target.name == scheme } if target == nil UI.error "Invalid scheme <#{scheme}>" UI.error "Valid schemes: #{project.native_targets.map { |target| target.name }.join(", ")}" return end build_configuration = target.build_configurations.first bundle = build_configuration.resolve_build_setting('PRODUCT_BUNDLE_IDENTIFIER') portal_team_id = build_configuration.resolve_build_setting('DEVELOPMENT_TEAM') flavor = build_configuration.resolve_build_setting('FLAVOR') # the platform defautl values are not considered yet so SDKROOT is not resolved # (https://www.rubydoc.info/gems/xcodeproj/Xcodeproj%2FProject%2FObject%2FAbstractTarget:resolved_build_setting) platform = scheme == "Generic_iOS" ? "ios" : "tvos" build_number = build_configuration.resolve_build_setting('CURRENT_PROJECT_VERSION') return bundle, portal_team_id, flavor, platform, build_number end def teams_map map = {} client = Spaceship::Portal.login() client.teams.each do |team| map[team['teamId']] = team['name'] end return map end teams_map = teams_map() platform :ios do desc "Run Swiftlint" lane :swiftlintReport do swiftlint(config_file: "./fastlane/swiftlintrules.yml") end lane :deploy_app do |options| scheme = options[:scheme] # if the flavor is provided, fetch its files into the Generic target flavor = options[:flavor] if (scheme == "Generic_iOS" || scheme == "Generic_tvOS") && flavor != nil UI.message "Setup Generic flavor: #{flavor}" sh("../videofutur/Scripts/setFlavor.sh", flavor) #UI.message "Wait a bit to let the packages refresh end" #sleep(20) end # get the bundle identifier and Developer Portal team id bundle, portal_team_id, flavor, platform, build_number = getSchemeInfo(scheme) if bundle == nil || portal_team_id == nil UI.user_error! "No Developer Portal team for scheme <#{scheme}>" end UI.message "Resolved scheme info - flavor: #{flavor}, bundle: #{bundle}, portal_team_id: #{portal_team_id}, platform: #{platform}" # get the AppStore Connect team id from the Developer Portal team id team_name = teams_map[portal_team_id] if team_name == nil UI.user_error! "No App Store Connect team found for Developer Portal team <#{portal_team_id}>" end UI.message "Available teams: #{teams_map}" # sync the main app provisioning profile match(type: "appstore", git_branch: portal_team_id, clone_branch_directly: true, app_identifier: bundle, platform: platform, readonly: true) # sync the NotificationService extension provisioning profile when building for the ios platform if platform == "ios" match(type: "appstore", git_branch: portal_team_id, clone_branch_directly: true, app_identifier: "#{bundle}.notificationservice", platform: platform, readonly: true) end # sync the TVTopShelf extension provisioning profile when building for the tvos platform if platform == "tvos" match(type: "appstore", git_branch: portal_team_id, clone_branch_directly: true, app_identifier: "#{bundle}.tvtopshelf", platform: platform, readonly: true) end # build the scheme ipa = build(scheme, flavor, build_number, platform) # upload the binary to the AppStore to_testflight(ipa, team_name) end lane :deploy_all do |options| deploy_configs(configs: all_configs, scheme: options[:scheme]) UI.message "Finished deploying all configs!" end lane :deploy_custom do |options| deploy_configs(configs: custom_configs, scheme: options[:scheme]) UI.message "Finished deploying custom configs!" end lane :deploy_configs do |options| configs = options[:configs] || [] scheme = options[:scheme] configs.select { |config| !scheme || scheme == config[:scheme] }.each { |config| config[:flavors].each { |flavor| deploy_app(scheme: config[:scheme], flavor: flavor) } } end lane :match_update do |options| type = options[:type] || "appstore" # Get the team config team_alias = options[:team] if team_alias == nil require "spaceship" clientPortal = Spaceship::Portal.login() team_id = Spaceship::Portal.select_team team_config = teams_config[team_id] else filter = teams_config.filter { |team_id, config| config["alias"] == team_alias } team_id = filter.keys.first team_config = filter.values.first end if team_id == nil || team_config == nil UI.user_error! "No Apple developer team for alias <#{team_alias}>" end team_alias = team_config["alias"] UI.message "Match update for team #{team_alias} (##{team_id})" # iOS apps app_ids_ios = team_config["ios_apps"] if app_ids_ios && app_ids_ios.count() > 0 # for each iOS app id, add its Notification Service counterpart ids = app_ids_ios + app_ids_ios.map { |id| "#{id}.notificationservice" } UI.message "Update iOS provisioning profiles for #{ids}" match(type: type, git_branch: team_id, team_id: team_id, app_identifier: ids, platform: "ios", clone_branch_directly: true, verbose: match_verbose) end # tvOS apps app_ids_tvos = team_config["tvos_apps"] if app_ids_tvos && app_ids_tvos.count() > 0 # for each tvOS app id, add its TV Top Shelf counterpart ids = app_ids_tvos + app_ids_tvos.map { |id| "#{id}.tvtopshelf" } UI.message "Update tvOS provisioning profiles for #{ids}" match(type: type, git_branch: team_id, team_id: team_id, app_identifier: ids, platform: "tvos", clone_branch_directly: true, verbose: match_verbose) end end lane :match_update_all do |options| teams_config.each do |team_id, config| team_alias = config["alias"] UI.message "Match update for team #{team_alias} (##{team_id})" match_update(team: team_alias) end end lane :upload_ipa do |options| filename = options[:ipa] portal_team_id = options[:team_id] team_name = teams_map[portal_team_id] if team_name == nil UI.user_error! "No App Store Connect team found for Developer Portal team <#{portal_team_id}>" end to_testflight(filename, team_name) end lane :get_apps_names_and_versions do |options| require "spaceship" clientPortal = Spaceship::Portal.login() teamId = Spaceship::Portal.select_team UI.message "Team: #{teamId}" clientTunes = Spaceship::Tunes.login() #Spaceship::Tunes.select_team UI.message "Apps: #{clientTunes.teams}" all_apps = "" clientTunes.teams.each do |team| ENV['FASTLANE_ITC_TEAM_ID'] = "#{team['providerId']}" Spaceship::Tunes.select_team Spaceship::Tunes::Application.all.collect do |app| begin live_version = app.get_live_app_store_version.version_string all_apps << "#{app.name} #{live_version} #{app.bundle_id}\n" UI.message "#{app.name} #{live_version} #{app.bundle_id}\n" rescue all_apps << "#{app.name} NO Live Version \n" UI.message "#{app.name} NO Live Version \n" end end end File.write('all_apps', all_apps[0..-3]) end lane :match_import_example do |options| # Example of import command: # match import --type appstore --skip_provisioning_profiles true --clone_branch_directly true --git_branch XXXXXXXXXX --team_id XXXXXXXXXX --app_identifier XXXXXXXXXX --platform ios end lane :match_nuke_example do |options| # Example of nuke command: # bundle exec fastlane run match_nuke type:appstore skip_provisioning_profiles:true clone_branch_directly:true git_branch:XXXXXXXXXX team_id:XXXXXXXXXX safe_remove_certs:true end end`./Appfile`
# app_identifier("[[APP_IDENTIFIER]]") # The bundle identifier of your app apple_id "XXXXXXXXXX" # Your Apple email address ENV['FASTLANE_USER'] = "XXXXXXXXXX" ENV['FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD'] = "XXXXXXXXXX" # For more information about the Appfile, see: # https://docs.fastlane.tools/advanced/#appfilefastlane gems
Gem Version Update-Status fastlane 2.220.0 ✅ Up-To-Date Loaded fastlane plugins:
No plugins Loaded
Loaded gems
Gem Version error_highlight 0.5.1 did_you_mean 1.6.3 syntax_suggest 1.0.2 bundler 2.4.8 pathname 0.2.1 rake 13.2.0 base64 0.2.0 nkf 0.2.0 rexml 3.2.6 CFPropertyList 3.0.7 public_suffix 5.0.5 addressable 2.8.6 artifactory 3.0.17 atomos 0.1.3 aws-eventstream 1.3.0 aws-partitions 1.907.0 aws-sigv4 1.8.0 jmespath 1.6.2 aws-sdk-core 3.191.6 aws-sdk-kms 1.78.0 aws-sdk-s3 1.146.1 babosa 1.0.4 claide 1.1.0 colored 1.2 colored2 3.1.2 highline 2.0.3 commander 4.6.0 declarative 0.0.20 digest-crc 0.6.5 domain_name 0.6.20240107 dotenv 2.8.1 emoji_regex 3.2.3 excon 0.110.0 faraday-em_http 1.0.0 faraday-em_synchrony 1.0.0 faraday-excon 1.1.0 faraday-httpclient 1.0.1 multipart-post 2.4.0 faraday-multipart 1.0.4 faraday-net_http 1.0.1 faraday-net_http_persistent 1.2.0 faraday-patron 1.0.0 faraday-rack 1.0.0 faraday-retry 1.0.3 ruby2_keywords 0.0.5 faraday 1.10.3 http-cookie 1.0.5 faraday-cookie_jar 0.0.7 faraday_middleware 1.2.0 fastimage 2.3.1 gh_inspector 1.1.3 jwt 2.8.1 multi_json 1.15.0 os 1.1.4 signet 0.19.0 googleauth 1.8.1 httpclient 2.8.3 mini_mime 1.1.5 trailblazer-option 0.1.2 uber 0.1.0 representable 3.2.0 retriable 3.1.2 google-apis-core 0.11.3 google-apis-androidpublisher_v3 0.54.0 google-apis-playcustomapp_v1 0.13.0 google-cloud-env 1.6.0 google-apis-iamcredentials_v1 0.17.0 google-apis-storage_v1 0.31.0 google-cloud-errors 1.4.0 google-cloud-core 1.7.0 google-cloud-storage 1.47.0 json 2.7.2 mini_magick 4.12.0 naturally 2.2.1 optparse 0.4.0 plist 3.7.1 rubyzip 2.3.2 security 0.1.5 simctl 1.6.10 terminal-notifier 2.0.0 unicode-display_width 2.5.0 terminal-table 3.0.2 tty-screen 0.8.2 tty-cursor 0.7.1 tty-spinner 0.9.3 word_wrap 1.0.0 nanaimo 0.3.0 xcodeproj 1.24.0 rouge 2.0.7 xcpretty 0.3.0 xcpretty-travis-formatter 1.0.1 generated on: 2024-06-05