diff --git a/appstoreconnect/capabilities.go b/appstoreconnect/capabilities.go index 6b0e8b38..3eb77c7a 100644 --- a/appstoreconnect/capabilities.go +++ b/appstoreconnect/capabilities.go @@ -78,6 +78,18 @@ var ServiceTypeByKey = map[string]CapabilityType{ "com.apple.developer.ubiquity-container-identifiers": Ignored, } +// UnsupportedEntitlements contains entitlements not supported via the API and this step, +// profile needs to be manually generated on Apple Developer Portal +var UnsupportedEntitlements = []string{ + "com.apple.developer.contacts.notes", + "com.apple.developer.carplay-audio", + "com.apple.developer.carplay-communication", + "com.apple.developer.carplay-charging", + "com.apple.developer.carplay-maps", + "com.apple.developer.carplay-parking", + "com.apple.developer.carplay-quick-ordering", +} + // CapabilitySettingAllowedInstances ... type CapabilitySettingAllowedInstances string diff --git a/autoprovision/entitlements.go b/autoprovision/entitlements.go index 29b6bccf..82322028 100644 --- a/autoprovision/entitlements.go +++ b/autoprovision/entitlements.go @@ -70,6 +70,19 @@ func dataProtectionEquals(entVal string, cap appstoreconnect.BundleIDCapability) return true, nil } +// ContainsUnsupportedEntitlement returns an error if an entitlement is used that we can not generate using the API +func ContainsUnsupportedEntitlement(entitlementsByBundleID map[string]serialized.Object, unsupportedEntitlements []string) error { + for id, entitlements := range entitlementsByBundleID { + for entitlement := range entitlements { + if sliceutil.IsStringInSlice(entitlement, unsupportedEntitlements) { + return fmt.Errorf("unsupported entitlement (%s) set for bundle ID %s", entitlement, id) + } + } + } + + return nil +} + // AppearsOnDeveloperPortal reports whether the given (project) Entitlement needs to be registered on Apple Developer Portal or not. // List of services, to be registered: https://developer.apple.com/documentation/appstoreconnectapi/capabilitytype. func (e Entitlement) AppearsOnDeveloperPortal() bool { diff --git a/autoprovision/entitlements_test.go b/autoprovision/entitlements_test.go index fa60a7f3..f92e1c70 100644 --- a/autoprovision/entitlements_test.go +++ b/autoprovision/entitlements_test.go @@ -3,6 +3,7 @@ package autoprovision_test import ( "testing" + "github.com/bitrise-io/xcode-project/serialized" "github.com/bitrise-steplib/steps-ios-auto-provision-appstoreconnect/autoprovision" "github.com/stretchr/testify/require" ) @@ -100,3 +101,61 @@ func TestICloudContainers(t *testing.T) { }) } } + +func TestContainsUnsupportedEntitlement(t *testing.T) { + tests := []struct { + name string + entitlementsByBundleID map[string]serialized.Object + unsupportedEntitlements []string + wantErr bool + }{ + { + name: "no entitlements", + entitlementsByBundleID: map[string]serialized.Object{ + "com.bundleid": map[string]interface{}{}, + }, + unsupportedEntitlements: []string{"com.entitlements-unsupported"}, + }, + { + name: "contains unsupported entitlement", + entitlementsByBundleID: map[string]serialized.Object{ + "com.bundleid": map[string]interface{}{ + "com.entitlement-supported": true, + "com.entitlement-unsupported": true, + }, + }, + unsupportedEntitlements: []string{"com.entitlement-unsupported"}, + wantErr: true, + }, + { + name: "contains unsupported entitlement, multiple bundle IDs", + entitlementsByBundleID: map[string]serialized.Object{ + "com.bundleID1": map[string]interface{}{ + "com.entitlement-supported": true, + }, + "com.bundleid": map[string]interface{}{ + "com.entitlement-supported": true, + "com.entitlement-unsupported": true, + }, + }, + unsupportedEntitlements: []string{"com.entitlement-unsupported"}, + wantErr: true, + }, + { + name: "all entitlements supported", + entitlementsByBundleID: map[string]serialized.Object{ + "com.bundleid": map[string]interface{}{ + "com.entitlement-supported": true, + }, + }, + unsupportedEntitlements: []string{}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := autoprovision.ContainsUnsupportedEntitlement(tt.entitlementsByBundleID, tt.unsupportedEntitlements); (err != nil) != tt.wantErr { + t.Errorf("ContainsUnsupportedEntitlement() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/main.go b/main.go index d620b1e9..e325b8a9 100644 --- a/main.go +++ b/main.go @@ -385,6 +385,10 @@ func main() { log.Printf("- %s", id) } + if err := autoprovision.ContainsUnsupportedEntitlement(entitlementsByBundleID, appstoreconnect.UnsupportedEntitlements); err != nil { + failf("Error: %v. Generate provisioning profile manually on Apple Developer Portal and use the Certificate and profile installer Step.", err) + } + platform, err := projHelper.Platform(config) if err != nil { failf("Failed to read project platform: %s", err)