Bug 41045 - Packaging an IPA using xbuild with the 'com.apple.developer.icloud-container-environment' entitlement always has "Development" embedded
Summary: Packaging an IPA using xbuild with the 'com.apple.developer.icloud-container-...
Status: RESOLVED FIXED
Alias: None
Product: iOS
Classification: Xamarin
Component: MSBuild ()
Version: XI 9.10 (C8)
Hardware: Macintosh Mac OS
: Low enhancement
Target Milestone: Untriaged
Assignee: Jeffrey Stedfast
URL:
Depends on:
Blocks:
 
Reported: 2016-05-12 05:49 UTC by Matthew Robbins
Modified: 2018-04-02 21:45 UTC (History)
3 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FIXED

Description Matthew Robbins 2016-05-12 05:49:31 UTC
When an iOS app has the 'com.apple.developer.icloud-container-environment' to configure an iCloud container, xbuild always injects a "Development" element into the final IPA.

This is an issue because the final IPA cannot be submitted via the Application Loader. Apple always rejects IPAs that contain "Development" under 'com.apple.developer.icloud-container-environment'.

The "Archive For Publishing" and "Sign For Distribution" processes within Xamarin Studio DO NOT cause this behaviour ot happen.

In the open sourced build task code for Xamarin.iOS there is a suspicious looking code snippet I suspect is the culprit:

protected virtual PDictionary GetCompiledEntitlements(MobileProvision profile, PDictionary template)
{
	var entitlements = new PDictionary();

	if (profile != null && MergeProfileEntitlements)
	{
		// start off with the settings from the provisioning profil
		foreach (var item in profile.Entitlements)
		{
			if (!AllowedProvisioningKeys.Contains(item.Key))
				continue;

			var value = item.Value;

		>>>>>>	if (item.Key == "com.apple.developer.icloud-container-environment") <<<<<
		>>>>>>		value = new PString("Development");                         <<<<<

			// ..
		}
	}
}

https://github.com/xamarin/xamarin-macios/blob/2edb2ae4f5bb371a7006731987717c01f8725420/msbuild/Xamarin.MacDev.Tasks.Core/Tasks/CompileEntitlementsTaskBase.cs
Comment 1 Matthew Robbins 2016-05-12 05:55:19 UTC
=== Xamarin Studio Business ===

Version 6.1 (build 817)
Installation UUID: 0c4328cb-e1b1-4543-8254-d92b3ee4da80
Runtime:
	Mono 4.4.0 (mono-4.4.0-branch/fcf7a6d Tue Apr 26 12:01:18 EDT 2016) (64-bit)
	GTK+ 2.24.23 (Raleigh theme)

	Package version: 404000148

=== NuGet ===

Version: 3.3.0.0

=== Xamarin.Profiler ===

Not Installed

=== Apple Developer Tools ===

Xcode 7.3.1 (10188.1)
Build 7D1014

=== Xamarin.iOS ===

Version: 9.9.0.719 (Xamarin Business)
Hash: 3afb4af
Branch: master
Build date: 2016-04-24 15:13:41-0400

=== Xamarin.Android ===

Version: 6.1.99.224 (Xamarin Business)
Android SDK: /Users/matthewrobbins/Library/Developer/Xamarin/android-sdk-macosx
	Supported Android versions:
		2.3    (API level 10)
		4.0.3  (API level 15)
		4.1    (API level 16)
		4.2    (API level 17)
		4.3    (API level 18)
		4.4    (API level 19)
		4.4.87 (API level 20)
		5.0    (API level 21)
		5.1    (API level 22)
		6.0    (API level 23)
		6.0.99 (API level 24)

SDK Tools Version: 25.1.3
SDK Platform Tools Version: 23.1
SDK Build Tools Version: 23.0.3

Java SDK: /usr
java version "1.7.0_67"
Java(TM) SE Runtime Environment (build 1.7.0_67-b01)
Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)

Android Designer EPL code available here:
https://github.com/xamarin/AndroidDesigner.EPL

=== Xamarin Android Player ===

Version: 0.6.5
Location: /Applications/Xamarin Android Player.app

=== Xamarin.Mac ===

Version: 2.9.0.719 (Xamarin Business)

=== Build Information ===

Release ID: 601000817
Git revision: 2335763551f9db8296b08542035977b899b7f3b7
Build date: 2016-04-25 10:45:36-04
Xamarin addins: 7f8c9ab2a981143a87fbd5adbde3f5890a838fde
Build lane: monodevelop-lion-cycle8-preview

=== Operating System ===

Mac OS X 10.11.4
Darwin JobAdders-iMac-6.local 15.4.0 Darwin Kernel Version 15.4.0
    Fri Feb 26 22:08:05 PST 2016
    root:xnu-3248.40.184~3/RELEASE_X86_64 x86_64

=== Enabled user installed addins ===

MFractor 2.00.00
Comment 2 Jeffrey Stedfast 2016-05-12 10:39:29 UTC
The build always sets Development because there's no way to decide what the user intends to use it for (Production vs Development).

The Publishing workflow in Xamarin Studio is what sets it to Production and is what users are expected to use for publishing to the App Store/etc.


That said, you'll notice the second loop in that method will override any values set in the first loop. This means that if you edit your Entitlements.plist and set the value to Production there, it will be set as Production in the IPA that is built as part of the build process.
Comment 3 Matthew Robbins 2016-05-13 00:30:13 UTC
HI Jeff,

Ok, understood.

Just to make sure I have my head around this let me re-iterate what you've said... Including the "Development" item is a delibrate choice by the Xamarin.iOS team so that you do the bundle and sign process very deliberately inside the ID.

My understanding is build servers can trigger ad-hoc builds that can be sent to testers via HockerApp or similiar but as soon as we want to publish to iTunes we should use the in-IDE bundling?
Comment 4 Jeffrey Stedfast 2016-05-13 00:41:09 UTC
Correct, that's the way it was designed (for better or worse).

That doesn't mean it has to necessarily stay that way. Originally, the intention was actually to remove the whole build-an-IPA-as-part-of-the-build-process once we added the archiving logic, but then it was brought to our attention that people wanted to be able to build IPAs in their CI, so we added the feature back. Since they only needed "Development", that's the only output it currently produces.

(the other piece of the puzzle is that the icloud environment key is fairly new, I think as of Xcode7? and so the original IPA msbuild implementation never had support for setting any other value other than having the user override it in the Entitlements.plist in their project)
Comment 5 Matthew Robbins 2016-05-13 00:58:07 UTC
It'd be very useful for CI builds to be able to use the production icloud environment key. A command line argument like '/p:com.apple.developer.icloud-container-environment=Production,Development' or similar would be nice :)

I can hack my way around this with T4 scripts for the moment and/or just do the production builds by hand... In an ideal world I'd just pickup the last IPA from our build server though.
Comment 6 Matthew Robbins 2016-06-02 11:43:37 UTC
Jeff, I'm satisfied with the answer you provided. Marking this as resolved on my end.
Comment 7 stefan@kwingle.com 2017-02-09 09:22:40 UTC
Guys, this is seriously wrong!

Reason 1: Of course are people using CI to upload their builds to Testflight. The "fastlane" command line tools (https://fastlane.tools/) are specifically designed for that and are being used by a lot of developers including us. Now since integrating iCloud support in our app, it's not working anymore.

Reason 2: This delicate detail is nowhere mentioned in your CI and troubleshooting guidelines. It should be mentioned at least here: https://developer.xamarin.com/guides/ios/watch/deployment/appstore/#Invalid_Code_Signing_Entitlements
This would have saved us from revoking and re-generating provisioning profiles and messing around with project settings :(

Reason 3: How can you not make this optional like Matthew already proposed? Manual deployment really isn't an alternative. Especially not when you have multiple developers working on the same project. This goes twice for iOS projects with all the certificate and provisioning profile hassle for production builds. 

@Matthew: Can you please give us a hint how to solve this with scripts?

Thanks,
Stefan
Comment 8 Alexander Borodin 2018-04-02 21:45:34 UTC
Stefan - agreed.

An alternative approach is to make the "archive/publish" functionality available via command-line or as an msbuild target (much like "PackageForAndroid"), so that this IDE functionality can be reproduced in a CI environment.

Where can such a feature request be logged?