fix: iOS uploads fail with shorebird release due to extension bundle version not set
App ID: 6983d7ed-9500-41fb-aa7a-d20543b232f2
Description
Firebase instructions call for adding an extension to report when notifications are received by a device. Fastlane fails to upload the ipa, and it succeeds when it is a plain flutter build.
Shorebird also lists this NotificationService as a flavor.
app_id: 6983d7ed-9500-41fb-aa7a-d20543b232f2
flavors:
NotificationService: 72139244-dd00-493e-9c8f-7aec4309dba7
Steps To Reproduce
- Follow instructions for adding a NotificationService.
- Run shorebird release
Expected Behavior
It should build and successfully upload.
Additional Context
[!] Error uploading ipa file:
[Application Loader Error Output]: ERROR: [ContentDelivery.Uploader] Asset validation failed (90056) This bundle Payload/Runner.app/PlugIns/NotificationService.appex is invalid. The Info.plist file is missing the required key: CFBundleVersion. Please find more information about CFBundleVersion at https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleversion (ID: 5e38f6c2-7b21-4013-8a58-ada42564f1ec)
[Application Loader Error Output]: ERROR: [ContentDelivery.Uploader] Asset validation failed (90360) Missing Info.plist value. A value for the key 'CFBundleVersion' in bundle Runner.app/PlugIns/NotificationService.appex is required. (ID: ae44831f-137e-45f6-9230-3a43b07ef48d)
[Application Loader Error Output]: Error uploading '/var/folders/hc/ty5dzztd7xnf2c2my5dln4xw0000gn/T/045fada8-818e-4111-9679-e3242ea6c7a7.ipa'.
[Application Loader Error Output]: Asset validation failed This bundle Payload/Runner.app/PlugIns/NotificationService.appex is invalid. The Info.plist file is missing the required key: CFBundleVersion. Please find more information about CFBundleVersion at https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleversion (ID: 5e38f6c2-7b21-4013-8a58-ada42564f1ec) (90056)
[Application Loader Error Output]: Asset validation failed Missing Info.plist value. A value for the key 'CFBundleVersion' in bundle Runner.app/PlugIns/NotificationService.appex is required. (ID: ae44831f-137e-45f6-9230-3a43b07ef48d) (90360)
[Application Loader Error Output]: The call to the altool completed with a non-zero exit status: 1. This indicates a failure.
Can you share the flutter build command that results in a successful build?
Also related https://github.com/shorebirdtech/shorebird/issues/1703
Potentially related to https://github.com/shorebirdtech/shorebird/issues/1956 as well
The reproduction steps are incomplete. Can you share what you did that triggered Error uploading ipa file? That output doesn't appear to be from shorebird release.
Uploading manually via xcode works fine. Building with flutter build also seems to upload fine. So it seems like there's something happening with the output that isn't quite aligned with what altool (fastlane's underlying client) expects.
fastlane_require 'spaceship'
default_platform(:ios)
def get_version()
version_number = ENV['VERSION_NUMBER']
return version_number
end
def get_build()
build_number = ENV['BUILD_NUMBER']
return build_number
end
platform :ios do
desc "Prepare"
lane :prebuild do
build_number = get_build()
version_number = get_version()
increment_build_number(
build_number: build_number,
xcodeproj: "./Runner.xcodeproj"
)
increment_version_number(
version_number: version_number,
xcodeproj: "./Runner.xcodeproj"
)
update_plist(
plist_path: "./NotificationService/Info.plist",
block: proc do |plist|
plist[:CFBundleShortVersionString] = version_number
plist[:CFBundleVersion] = build_number
end
)
end
desc "Build"
lane :build do
build_number = get_build()
version_number = get_version()
sh <<~CMD
shorebird release ios -- \
--build-name #{version_number} \
--build-number #{build_number}
CMD
end
desc "Deploy Internal"
lane :deploy_internal do
build_number = get_build()
version_number = get_version()
app_store_connect_api_key(
is_key_content_base64: true,
in_house: false,
duration: 600,
)
pilot(
ipa: "../build/ios/ipa/Runner.ipa",
app_version: version_number,
build_number: build_number,
skip_waiting_for_build_processing: true,
skip_submission: true,
distribute_external: false,
notify_external_testers: false
)
end
end
It could be related to this. I had bad values set for the config, it wasn't inheriting the flutter variables. I will report back after testing this change.
Relevant Discord thread, starting at this message: https://discord.com/channels/1030243211995791380/1250070546008379423/1255185635514257479
It sounds like the issue is that Fastlane's gym tool handled updating extension versions, and altool does not.
Excerpts from the Discord thread:
I tried setting the versionNumber to $(FLUTTER_BUILD_NAME) in xcode, but it got re-set to MARKETING_VERSION when I ran shorebird release. I am trying to now set MARKETING_VERSION to $(FLUTTER_BUILD_NAME)
It looks like it removes versionNumber from the field for the NotificationService.appex subpackage. I assume that means it will inherit from the parent app? I will try to upload this
and
My build finally succeeded e2e with shorebird. I couldn't find consistent documentation for Flutter with Notification Service Extensions. Ultimately, the extension needs to have its respective xcconfig files and inherit from the flutter Generated.xcconfig, for instance
#include "Pods/Target Support Files/Pods-NotificationService/Pods-NotificationService.debug.xcconfig"
#include "Flutter/Generated.xcconfig"
The project needs to have each target source its respective configs. And, also set the CFBundleVersion and CFBundleShortVersionString to the same values as the main Info.plist, for the extension
I think this was ok prior because I was using xcode build and it must do this behind the scenes.
There is this new "extension-safe" version of the Flutter engine that flutter builds: https://github.com/flutter/engine/blob/main/ci/builders/mac_ios_engine.json#L267 That doesn't have anything to do with this, correct?
Nevermind, I bet that "extension-safe" flutter is for use within extensions.
Relevant Discord thread, starting at this message: https://discord.com/channels/1030243211995791380/1250070546008379423/1255185635514257479
It sounds like the issue is that Fastlane's
gymtool handled updating extension versions, andaltooldoes not.Excerpts from the Discord thread:
I tried setting the versionNumber to $(FLUTTER_BUILD_NAME) in xcode, but it got re-set to MARKETING_VERSION when I ran shorebird release. I am trying to now set MARKETING_VERSION to $(FLUTTER_BUILD_NAME) It looks like it removes versionNumber from the field for the NotificationService.appex subpackage. I assume that means it will inherit from the parent app? I will try to upload thisand
My build finally succeeded e2e with shorebird. I couldn't find consistent documentation for Flutter with Notification Service Extensions. Ultimately, the extension needs to have its respective xcconfig files and inherit from the flutter Generated.xcconfig, for instance #include "Pods/Target Support Files/Pods-NotificationService/Pods-NotificationService.debug.xcconfig" #include "Flutter/Generated.xcconfig" The project needs to have each target source its respective configs. And, also set the CFBundleVersion and CFBundleShortVersionString to the same values as the main Info.plist, for the extensionI think this was ok prior because I was using xcode build and it must do this behind the scenes.
This discord response doesn't provide enough information for troubleshooting...
I believe the inclusion of "NotificationService" as a flavor was an old bug we've since fixed. I think it can just be removed from the flavor list: https://github.com/shorebirdtech/shorebird/issues/1703
I'm not certain, but the fix here might just be to remove the "NotificationService" flavor from shorebird.yaml and try running shorebird release again?
I believe this has been fixed