Open AArnott opened 3 months ago
A trivial workaround would be to set BuildIpa yourself:
dotnet build -f net8.0-ios -r ios-arm64 -p:BuildIpa=true
since Publish is pretty much just Build with BuildIpa=true.
You might have to set IpaPackageDir to some value too, to get the .ipa in the directory where you expect it:
dotnet build -f net8.0-ios -r ios-arm64 -p:BuildIpa=true -p:IpaPackageDir=publishdir
Wow. This is so much not what is shown in the official docs: https://learn.microsoft.com/en-us/dotnet/maui/ios/deployment/publish-cli?view=net-maui-8.0
I came here because the official documented approach does not produce the .ipa. The method give here does. Thank you @AArnott .
The .ipa package is not constructed, and an incomplete log message is emitted claiming success, when an iOS project is built with
Build
thenPublish
target order.Repro steps
dotnet build -f net8.0-ios -r ios-arm64
succeeds and builds just the .dlldotnet build -f net8.0-ios -r ios-arm64 -t:publish
succeeds and creates the .ipa package:dotnet build -f net8.0-ios -r ios-arm64 -t:build,publish
Expected
The build succeeds as well as the publish target, which constructs the .ipa package.
Actual
The build succeeds, but the Publish target skips building the .ipa package, yet prints an incomplete message trying to say that it did (though it didn't):
msbuild.binlog.zip
Analysis
This happens because the Build target leads the
_CoreCreateIpa
target to execute due to target dependencies, but that target is skipped because its condition ('$(BuildIpa)' == 'true'
) is false.BuildIpa
is a property that is only set totrue
by the_PrePublish
target. But that target doesn't run as part of Build -- only as part of Publish. So as long as the Publish target is listed first on the command line or as the only target, it works because_PrePublish
executes before_CoreCreateIpa
. But it is vulnerable to target execution order and publish never happens if Build is also built (first).This is particularly a problem when a repo is built through traversal projects (Microsoft.Build.Traversal SDK) because even if I ask the dirs.proj to build targets in "Publish,Build" order, the traversal only propagates those targets to the iOS/Maui project in Build,Publish order.
In general, MSBuild .targets files should be authored such that if the order in which the Targets execute is significant, that order is guaranteed rather than just relying on chance. While docs may suggest publishing an iOS app with
dotnet publish
, doing so leads to overbuilding a repo when the iOS project has already been largely built (and signed) by a prior step in the build. Builds can be much faster when they never build the same target twice, and traversal projects have allowed me to do that.Workaround
I've hacked a workaround for the time being that ensures target order matches the Microsoft.iOS.SDK's assumptions. It relies on the fact that I set the
CI
msbuild property totrue
in CI builds where I build traversal projects.The workaround is to add this target to my iOS project: