From 84adf1cd7b08d703275cde4411ddca40ddcc1e8e Mon Sep 17 00:00:00 2001 From: Laszlo Pusok Date: Tue, 31 May 2022 13:57:01 +0200 Subject: [PATCH 1/6] Added tempalteName: --- autocodesign/autocodesign.go | 5 +++-- .../devportalclient/appstoreconnect/profiles.go | 12 +++++++----- .../appstoreconnectclient/profiles.go | 9 +++++---- autocodesign/profiles.go | 14 +++++++------- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/autocodesign/autocodesign.go b/autocodesign/autocodesign.go index 89776cee..82cdb90b 100644 --- a/autocodesign/autocodesign.go +++ b/autocodesign/autocodesign.go @@ -77,7 +77,7 @@ type DevPortalClient interface { FindProfile(name string, profileType appstoreconnect.ProfileType) (Profile, error) DeleteProfile(id string) error - CreateProfile(name string, profileType appstoreconnect.ProfileType, bundleID appstoreconnect.BundleID, certificateIDs []string, deviceIDs []string) (Profile, error) + CreateProfile(name string, profileType appstoreconnect.ProfileType, bundleID appstoreconnect.BundleID, certificateIDs []string, deviceIDs []string, templateName string) (Profile, error) FindBundleID(bundleIDIdentifier string) (*appstoreconnect.BundleID, error) CheckBundleIDEntitlements(bundleID appstoreconnect.BundleID, appEntitlements Entitlements) error @@ -131,6 +131,7 @@ type CodesignAssetsOpts struct { BitriseTestDevices []devportalservice.TestDevice MinProfileValidityDays int FallbackToLocalAssetsOnAPIFailure bool + ProfileTemplateName string VerboseLog bool } @@ -206,7 +207,7 @@ func (m codesignAssetManager) EnsureCodesignAssets(appLayout AppLayout, opts Cod printMissingCodeSignAssets(missingAppLayout) // Ensure Profiles - newCodesignAssets, err := ensureProfiles(m.devPortalClient, distrType, certsByType, *missingAppLayout, devPortalDeviceIDs, opts.MinProfileValidityDays) + newCodesignAssets, err := ensureProfiles(m.devPortalClient, distrType, certsByType, *missingAppLayout, devPortalDeviceIDs, opts.MinProfileValidityDays, opts.ProfileTemplateName) if err != nil { switch { case errors.As(err, &ErrAppClipAppID{}): diff --git a/autocodesign/devportalclient/appstoreconnect/profiles.go b/autocodesign/devportalclient/appstoreconnect/profiles.go index 322d4e29..979d3cdf 100644 --- a/autocodesign/devportalclient/appstoreconnect/profiles.go +++ b/autocodesign/devportalclient/appstoreconnect/profiles.go @@ -156,8 +156,9 @@ func (s ProvisioningService) ListProfiles(opt *ListProfilesOptions) (*ProfilesRe // ProfileCreateRequestDataAttributes ... type ProfileCreateRequestDataAttributes struct { - Name string `json:"name"` - ProfileType ProfileType `json:"profileType"` + Name string `json:"name"` + ProfileType ProfileType `json:"profileType"` + TemplateType string `json:"templateName,omitempty"` } // ProfileCreateRequestDataRelationshipData ... @@ -201,7 +202,7 @@ type ProfileCreateRequest struct { } // NewProfileCreateRequest returns a ProfileCreateRequest structure -func NewProfileCreateRequest(profileType ProfileType, name, bundleIDID string, certificateIDs []string, deviceIDs []string) ProfileCreateRequest { +func NewProfileCreateRequest(profileType ProfileType, name, bundleIDID string, certificateIDs []string, deviceIDs []string, templateName string) ProfileCreateRequest { bundleIDData := ProfileCreateRequestDataRelationshipData{ ID: bundleIDID, Type: "bundleIds", @@ -233,8 +234,9 @@ func NewProfileCreateRequest(profileType ProfileType, name, bundleIDID string, c data := ProfileCreateRequestData{ Attributes: ProfileCreateRequestDataAttributes{ - Name: name, - ProfileType: profileType, + Name: name, + ProfileType: profileType, + TemplateType: templateName, }, Relationships: relationships, Type: "profiles", diff --git a/autocodesign/devportalclient/appstoreconnectclient/profiles.go b/autocodesign/devportalclient/appstoreconnectclient/profiles.go index be177a06..93bd83d3 100644 --- a/autocodesign/devportalclient/appstoreconnectclient/profiles.go +++ b/autocodesign/devportalclient/appstoreconnectclient/profiles.go @@ -159,8 +159,8 @@ func (c *ProfileClient) DeleteProfile(id string) error { } // CreateProfile ... -func (c *ProfileClient) CreateProfile(name string, profileType appstoreconnect.ProfileType, bundleID appstoreconnect.BundleID, certificateIDs []string, deviceIDs []string) (autocodesign.Profile, error) { - profile, err := c.createProfile(name, profileType, bundleID, certificateIDs, deviceIDs) +func (c *ProfileClient) CreateProfile(name string, profileType appstoreconnect.ProfileType, bundleID appstoreconnect.BundleID, certificateIDs []string, deviceIDs []string, templateName string) (autocodesign.Profile, error) { + profile, err := c.createProfile(name, profileType, bundleID, certificateIDs, deviceIDs, templateName) if err != nil { // Expired profiles are not listed via profiles endpoint, // so we can not catch if the profile already exist but expired, before we attempt to create one with the managed profile name. @@ -171,7 +171,7 @@ func (c *ProfileClient) CreateProfile(name string, profileType appstoreconnect.P return nil, fmt.Errorf("expired profile cleanup failed: %s", err) } - profile, err = c.createProfile(name, profileType, bundleID, certificateIDs, deviceIDs) + profile, err = c.createProfile(name, profileType, bundleID, certificateIDs, deviceIDs, templateName) if err != nil { return nil, err } @@ -218,7 +218,7 @@ func (c *ProfileClient) deleteExpiredProfile(bundleID *appstoreconnect.BundleID, return c.DeleteProfile(profile.ID) } -func (c *ProfileClient) createProfile(name string, profileType appstoreconnect.ProfileType, bundleID appstoreconnect.BundleID, certificateIDs []string, deviceIDs []string) (autocodesign.Profile, error) { +func (c *ProfileClient) createProfile(name string, profileType appstoreconnect.ProfileType, bundleID appstoreconnect.BundleID, certificateIDs []string, deviceIDs []string, templateName string) (autocodesign.Profile, error) { // Create new Bitrise profile on App Store Connect r, err := c.client.Provisioning.CreateProfile( appstoreconnect.NewProfileCreateRequest( @@ -227,6 +227,7 @@ func (c *ProfileClient) createProfile(name string, profileType appstoreconnect.P bundleID.ID, certificateIDs, deviceIDs, + templateName, ), ) if err != nil { diff --git a/autocodesign/profiles.go b/autocodesign/profiles.go index a84679d3..3c186597 100644 --- a/autocodesign/profiles.go +++ b/autocodesign/profiles.go @@ -25,7 +25,7 @@ func appIDName(bundleID string) string { func ensureProfiles(profileClient DevPortalClient, distrType DistributionType, certsByType map[appstoreconnect.CertificateType][]Certificate, app AppLayout, - devPortalDeviceIDs []string, minProfileDaysValid int) (*AppCodesignAssets, error) { + devPortalDeviceIDs []string, minProfileDaysValid int, templateName string) (*AppCodesignAssets, error) { // Ensure Profiles bundleIDByBundleIDIdentifer := map[string]*appstoreconnect.BundleID{} @@ -73,7 +73,7 @@ func ensureProfiles(profileClient DevPortalClient, distrType DistributionType, profileDeviceIDs = devPortalDeviceIDs } - profile, err := profileManager.ensureProfileWithRetry(profileType, bundleIDIdentifier, entitlements, certIDs, profileDeviceIDs, minProfileDaysValid) + profile, err := profileManager.ensureProfileWithRetry(profileType, bundleIDIdentifier, entitlements, certIDs, profileDeviceIDs, minProfileDaysValid, templateName) if err != nil { return nil, err } @@ -90,7 +90,7 @@ func ensureProfiles(profileClient DevPortalClient, distrType DistributionType, } // Capabilities are not supported for UITest targets. - profile, err := profileManager.ensureProfileWithRetry(profileType, wildcardBundleID, nil, certIDs, devPortalDeviceIDs, minProfileDaysValid) + profile, err := profileManager.ensureProfileWithRetry(profileType, wildcardBundleID, nil, certIDs, devPortalDeviceIDs, minProfileDaysValid, templateName) if err != nil { return nil, err } @@ -199,7 +199,7 @@ func (m profileManager) ensureBundleID(bundleIDIdentifier string, entitlements E return bundleID, nil } -func (m profileManager) ensureProfileWithRetry(profileType appstoreconnect.ProfileType, bundleIDIdentifier string, entitlements Entitlements, certIDs, deviceIDs []string, minProfileDaysValid int) (*Profile, error) { +func (m profileManager) ensureProfileWithRetry(profileType appstoreconnect.ProfileType, bundleIDIdentifier string, entitlements Entitlements, certIDs, deviceIDs []string, minProfileDaysValid int, templateName string) (*Profile, error) { var profile *Profile // Accessing the same Apple Developer Portal team can cause race conditions (parallel CI runs for example). // Between the time of finding and downloading a profile, it could have been deleted for example. @@ -210,7 +210,7 @@ func (m profileManager) ensureProfileWithRetry(profileType appstoreconnect.Profi } var err error - profile, err = m.ensureProfile(profileType, bundleIDIdentifier, entitlements, certIDs, deviceIDs, minProfileDaysValid) + profile, err = m.ensureProfile(profileType, bundleIDIdentifier, entitlements, certIDs, deviceIDs, minProfileDaysValid, templateName) if err != nil { if ok := errors.As(err, &ProfilesInconsistentError{}); ok { log.Warnf(" %s", err) @@ -228,7 +228,7 @@ func (m profileManager) ensureProfileWithRetry(profileType appstoreconnect.Profi return profile, nil } -func (m profileManager) ensureProfile(profileType appstoreconnect.ProfileType, bundleIDIdentifier string, entitlements Entitlements, certIDs, deviceIDs []string, minProfileDaysValid int) (*Profile, error) { +func (m profileManager) ensureProfile(profileType appstoreconnect.ProfileType, bundleIDIdentifier string, entitlements Entitlements, certIDs, deviceIDs []string, minProfileDaysValid int, templateName string) (*Profile, error) { fmt.Println() log.Infof(" Checking bundle id: %s", bundleIDIdentifier) log.Printf(" capabilities:") @@ -283,7 +283,7 @@ func (m profileManager) ensureProfile(profileType appstoreconnect.ProfileType, b fmt.Println() log.Infof(" Creating profile for bundle id: %s", bundleID.Attributes.Name) - profile, err = m.client.CreateProfile(name, profileType, *bundleID, certIDs, deviceIDs) + profile, err = m.client.CreateProfile(name, profileType, *bundleID, certIDs, deviceIDs, templateName) if err != nil { return nil, fmt.Errorf("failed to create profile: %w", err) } From a432d948eed5733529895b6709f0fd8dad3578b9 Mon Sep 17 00:00:00 2001 From: Laszlo Pusok <7979773+lpusok@users.noreply.github.com> Date: Tue, 10 Jan 2023 13:39:54 +0100 Subject: [PATCH 2/6] Tests fixed --- autocodesign/autocodesign_test.go | 6 +- .../appstoreconnectclient/profiles_test.go | 2 +- .../devportalclient/spaceship/profiles.go | 6 +- autocodesign/mock_DevPortalClient.go | 63 +++++++++---------- 4 files changed, 40 insertions(+), 37 deletions(-) diff --git a/autocodesign/autocodesign_test.go b/autocodesign/autocodesign_test.go index c768e69d..db3f008c 100644 --- a/autocodesign/autocodesign_test.go +++ b/autocodesign/autocodesign_test.go @@ -133,7 +133,7 @@ func Test_codesignAssetManager_EnsureCodesignAssets(t *testing.T) { }) devportalWithNoAppID.On("CreateBundleID", "io.test", "Bitrise io test").Return(createdAppID, nil). On("SyncBundleID", *createdAppID, mock.Anything).Return(nil). - On("CreateProfile", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + On("CreateProfile", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, ""). Return(newMockProfile(profileArgs{}), nil) appIDAndProfileFoundAppLayout := AppLayout{ @@ -398,11 +398,11 @@ func Test_GivenProfileExpired_WhenProfilesInconsistent_ThenItRetries(t *testing. // FindProfile client.On("DeleteProfile", expiredProfile.ID()).Return(nil).Once() client.On("CheckBundleIDEntitlements", mock.Anything, mock.Anything).Return(nil).Once() - client.On("CreateProfile", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, ProfilesInconsistentError{}).Once() + client.On("CreateProfile", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, "").Return(nil, ProfilesInconsistentError{}).Once() // FindProfile client.On("DeleteProfile", expiredProfile.ID()).Return(nil).Once() client.On("CheckBundleIDEntitlements", mock.Anything, mock.Anything).Return(nil).Once() - client.On("CreateProfile", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(validProfile, nil).Once() + client.On("CreateProfile", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, "").Return(validProfile, nil).Once() assetWriter := newDefaultMockAssetWriter() appLayout := AppLayout{ diff --git a/autocodesign/devportalclient/appstoreconnectclient/profiles_test.go b/autocodesign/devportalclient/appstoreconnectclient/profiles_test.go index 332a662e..0b9286de 100644 --- a/autocodesign/devportalclient/appstoreconnectclient/profiles_test.go +++ b/autocodesign/devportalclient/appstoreconnectclient/profiles_test.go @@ -106,7 +106,7 @@ func TestEnsureProfile_ExpiredProfile(t *testing.T) { }, } - profile, err := profileClient.CreateProfile("Bitrise iOS development - (io.bitrise.testapp)", appstoreconnect.IOSAppDevelopment, bundleID, []string{}, []string{}) + profile, err := profileClient.CreateProfile("Bitrise iOS development - (io.bitrise.testapp)", appstoreconnect.IOSAppDevelopment, bundleID, []string{}, []string{}, "") // Assert require.NoError(t, err) diff --git a/autocodesign/devportalclient/spaceship/profiles.go b/autocodesign/devportalclient/spaceship/profiles.go index ed496b41..3c98a56d 100644 --- a/autocodesign/devportalclient/spaceship/profiles.go +++ b/autocodesign/devportalclient/spaceship/profiles.go @@ -178,7 +178,11 @@ func (c *ProfileClient) DeleteProfile(id string) error { } // CreateProfile ... -func (c *ProfileClient) CreateProfile(name string, profileType appstoreconnect.ProfileType, bundleID appstoreconnect.BundleID, certificateIDs []string, deviceIDs []string) (autocodesign.Profile, error) { +func (c *ProfileClient) CreateProfile(name string, profileType appstoreconnect.ProfileType, bundleID appstoreconnect.BundleID, certificateIDs []string, deviceIDs []string, templateName string) (autocodesign.Profile, error) { + if templateName != "" { + return nil, fmt.Errorf("profile template name not supported with spaceship client") + } + log.Debugf("Creating provisioning profile with name: %s", name) cmd, err := c.client.createRequestCommand("create_profile", diff --git a/autocodesign/mock_DevPortalClient.go b/autocodesign/mock_DevPortalClient.go index 7aabbe29..d11c8a0e 100644 --- a/autocodesign/mock_DevPortalClient.go +++ b/autocodesign/mock_DevPortalClient.go @@ -1,4 +1,4 @@ -// Code generated by mockery 2.9.4. DO NOT EDIT. +// Code generated by mockery v2.14.0. DO NOT EDIT. package autocodesign @@ -40,9 +40,7 @@ func (_m *MockDevPortalClient) CreateBundleID(bundleIDIdentifier string, appIDNa r0 = rf(bundleIDIdentifier, appIDName) } else { if ret.Get(0) != nil { - r0, ok = ret.Get(0).(*appstoreconnect.BundleID) - if !ok { - } + r0 = ret.Get(0).(*appstoreconnect.BundleID) } } @@ -56,24 +54,22 @@ func (_m *MockDevPortalClient) CreateBundleID(bundleIDIdentifier string, appIDNa return r0, r1 } -// CreateProfile provides a mock function with given fields: name, profileType, bundleID, certificateIDs, deviceIDs -func (_m *MockDevPortalClient) CreateProfile(name string, profileType appstoreconnect.ProfileType, bundleID appstoreconnect.BundleID, certificateIDs []string, deviceIDs []string) (Profile, error) { - ret := _m.Called(name, profileType, bundleID, certificateIDs, deviceIDs) +// CreateProfile provides a mock function with given fields: name, profileType, bundleID, certificateIDs, deviceIDs, templateName +func (_m *MockDevPortalClient) CreateProfile(name string, profileType appstoreconnect.ProfileType, bundleID appstoreconnect.BundleID, certificateIDs []string, deviceIDs []string, templateName string) (Profile, error) { + ret := _m.Called(name, profileType, bundleID, certificateIDs, deviceIDs, templateName) var r0 Profile - if rf, ok := ret.Get(0).(func(string, appstoreconnect.ProfileType, appstoreconnect.BundleID, []string, []string) Profile); ok { - r0 = rf(name, profileType, bundleID, certificateIDs, deviceIDs) + if rf, ok := ret.Get(0).(func(string, appstoreconnect.ProfileType, appstoreconnect.BundleID, []string, []string, string) Profile); ok { + r0 = rf(name, profileType, bundleID, certificateIDs, deviceIDs, templateName) } else { if ret.Get(0) != nil { - r0, ok = ret.Get(0).(Profile) - if !ok { - } + r0 = ret.Get(0).(Profile) } } var r1 error - if rf, ok := ret.Get(1).(func(string, appstoreconnect.ProfileType, appstoreconnect.BundleID, []string, []string) error); ok { - r1 = rf(name, profileType, bundleID, certificateIDs, deviceIDs) + if rf, ok := ret.Get(1).(func(string, appstoreconnect.ProfileType, appstoreconnect.BundleID, []string, []string, string) error); ok { + r1 = rf(name, profileType, bundleID, certificateIDs, deviceIDs, templateName) } else { r1 = ret.Error(1) } @@ -104,9 +100,7 @@ func (_m *MockDevPortalClient) FindBundleID(bundleIDIdentifier string) (*appstor r0 = rf(bundleIDIdentifier) } else { if ret.Get(0) != nil { - r0, ok = ret.Get(0).(*appstoreconnect.BundleID) - if !ok { - } + r0 = ret.Get(0).(*appstoreconnect.BundleID) } } @@ -129,9 +123,7 @@ func (_m *MockDevPortalClient) FindProfile(name string, profileType appstoreconn r0 = rf(name, profileType) } else { if ret.Get(0) != nil { - r0, ok = ret.Get(0).(Profile) - if !ok { - } + r0 = ret.Get(0).(Profile) } } @@ -154,9 +146,7 @@ func (_m *MockDevPortalClient) ListDevices(UDID string, platform appstoreconnect r0 = rf(UDID, platform) } else { if ret.Get(0) != nil { - r0, ok = ret.Get(0).([]appstoreconnect.Device) - if !ok { - } + r0 = ret.Get(0).([]appstoreconnect.Device) } } @@ -179,9 +169,7 @@ func (_m *MockDevPortalClient) QueryAllIOSCertificates() (map[appstoreconnect.Ce r0 = rf() } else { if ret.Get(0) != nil { - r0, ok = ret.Get(0).(map[appstoreconnect.CertificateType][]Certificate) - if !ok { - } + r0 = ret.Get(0).(map[appstoreconnect.CertificateType][]Certificate) } } @@ -203,9 +191,7 @@ func (_m *MockDevPortalClient) QueryCertificateBySerial(serial big.Int) (Certifi if rf, ok := ret.Get(0).(func(big.Int) Certificate); ok { r0 = rf(serial) } else { - r0, ok = ret.Get(0).(Certificate) - if !ok { - } + r0 = ret.Get(0).(Certificate) } var r1 error @@ -227,9 +213,7 @@ func (_m *MockDevPortalClient) RegisterDevice(testDevice devportalservice.TestDe r0 = rf(testDevice) } else { if ret.Get(0) != nil { - r0, ok = ret.Get(0).(*appstoreconnect.Device) - if !ok { - } + r0 = ret.Get(0).(*appstoreconnect.Device) } } @@ -256,3 +240,18 @@ func (_m *MockDevPortalClient) SyncBundleID(bundleID appstoreconnect.BundleID, a return r0 } + +type mockConstructorTestingTNewMockDevPortalClient interface { + mock.TestingT + Cleanup(func()) +} + +// NewMockDevPortalClient creates a new instance of MockDevPortalClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewMockDevPortalClient(t mockConstructorTestingTNewMockDevPortalClient) *MockDevPortalClient { + mock := &MockDevPortalClient{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} From 9e26ebd8e671124e8f7de04ce983323036acfab0 Mon Sep 17 00:00:00 2001 From: Laszlo Pusok <7979773+lpusok@users.noreply.github.com> Date: Tue, 10 Jan 2023 18:50:40 +0100 Subject: [PATCH 3/6] Use map for distribution template name mapping --- autocodesign/autocodesign.go | 2 +- autocodesign/profiles.go | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/autocodesign/autocodesign.go b/autocodesign/autocodesign.go index 82cdb90b..4c4ed75d 100644 --- a/autocodesign/autocodesign.go +++ b/autocodesign/autocodesign.go @@ -131,7 +131,7 @@ type CodesignAssetsOpts struct { BitriseTestDevices []devportalservice.TestDevice MinProfileValidityDays int FallbackToLocalAssetsOnAPIFailure bool - ProfileTemplateName string + ProfileTemplateName map[DistributionType]string VerboseLog bool } diff --git a/autocodesign/profiles.go b/autocodesign/profiles.go index 3c186597..6d324d06 100644 --- a/autocodesign/profiles.go +++ b/autocodesign/profiles.go @@ -25,7 +25,7 @@ func appIDName(bundleID string) string { func ensureProfiles(profileClient DevPortalClient, distrType DistributionType, certsByType map[appstoreconnect.CertificateType][]Certificate, app AppLayout, - devPortalDeviceIDs []string, minProfileDaysValid int, templateName string) (*AppCodesignAssets, error) { + devPortalDeviceIDs []string, minProfileDaysValid int, distributionToTemplateName map[DistributionType]string) (*AppCodesignAssets, error) { // Ensure Profiles bundleIDByBundleIDIdentifer := map[string]*appstoreconnect.BundleID{} @@ -66,6 +66,12 @@ func ensureProfiles(profileClient DevPortalClient, distrType DistributionType, } profileType := platformProfileTypes[distrType] + templateName := distributionToTemplateName[distrType] + if templateName == "" { + log.Debugf("No profile tempalte name provided") + } else { + log.Printf("Profile template name: %s", templateName) + } for bundleIDIdentifier, entitlements := range app.EntitlementsByArchivableTargetBundleID { var profileDeviceIDs []string @@ -90,7 +96,7 @@ func ensureProfiles(profileClient DevPortalClient, distrType DistributionType, } // Capabilities are not supported for UITest targets. - profile, err := profileManager.ensureProfileWithRetry(profileType, wildcardBundleID, nil, certIDs, devPortalDeviceIDs, minProfileDaysValid, templateName) + profile, err := profileManager.ensureProfileWithRetry(profileType, wildcardBundleID, nil, certIDs, devPortalDeviceIDs, minProfileDaysValid, "") if err != nil { return nil, err } From 723034c3504b8d338a3c6e25d879e9cfb7cf0db9 Mon Sep 17 00:00:00 2001 From: Laszlo Pusok <7979773+lpusok@users.noreply.github.com> Date: Tue, 10 Jan 2023 20:13:15 +0100 Subject: [PATCH 4/6] Do not error out with profile attached tempaltes --- autocodesign/autocodesign.go | 15 +++++++++++++++ autocodesign/projectmanager/projectmanager.go | 18 ------------------ codesign/codesign.go | 5 +++++ 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/autocodesign/autocodesign.go b/autocodesign/autocodesign.go index 4c4ed75d..d8d4a3f2 100644 --- a/autocodesign/autocodesign.go +++ b/autocodesign/autocodesign.go @@ -239,3 +239,18 @@ func (m codesignAssetManager) EnsureCodesignAssets(appLayout AppLayout, opts Cod return codesignAssetsByDistributionType, nil } + +// ListProfileAttachedEntitlements ... +func (layout AppLayout) ListProfileAttachedEntitlements() map[string][]string { + bundleIDToTemplatedEntitlements := make(map[string][]string) + + for bundleID, entitlements := range layout.EntitlementsByArchivableTargetBundleID { + for entitlementKey, value := range entitlements { + if (Entitlement{entitlementKey: value}).IsProfileAttached() { + bundleIDToTemplatedEntitlements[bundleID] = append(bundleIDToTemplatedEntitlements[bundleID], entitlementKey) + } + } + } + + return bundleIDToTemplatedEntitlements +} diff --git a/autocodesign/projectmanager/projectmanager.go b/autocodesign/projectmanager/projectmanager.go index 8676396d..d23998d1 100644 --- a/autocodesign/projectmanager/projectmanager.go +++ b/autocodesign/projectmanager/projectmanager.go @@ -100,11 +100,6 @@ func (p Project) GetAppLayout(uiTestTargets bool) (autocodesign.AppLayout, error return autocodesign.AppLayout{}, fmt.Errorf("failed to read archivable targets' entitlements: %s", err) } - if ok, entitlement, bundleID := CanGenerateProfileWithEntitlements(archivableTargetBundleIDToEntitlements); !ok { - log.Errorf("Can not create profile with unsupported entitlement (%s) for the bundle ID %s, due to App Store Connect API limitations.", entitlement, bundleID) - return autocodesign.AppLayout{}, fmt.Errorf("please generate provisioning profile manually on Apple Developer Portal and use the Certificate and profile installer Step instead") - } - var uiTestTargetBundleIDs []string if uiTestTargets { log.Printf("UITest targets:") @@ -210,16 +205,3 @@ func (p Project) ForceCodesignAssets(distribution autocodesign.DistributionType, return nil } - -// CanGenerateProfileWithEntitlements checks all entitlements, whether they can be generated -func CanGenerateProfileWithEntitlements(entitlementsByBundleID map[string]autocodesign.Entitlements) (ok bool, badEntitlement string, badBundleID string) { - for bundleID, entitlements := range entitlementsByBundleID { - for entitlementKey, value := range entitlements { - if (autocodesign.Entitlement{entitlementKey: value}).IsProfileAttached() { - return false, entitlementKey, bundleID - } - } - } - - return true, "", "" -} diff --git a/codesign/codesign.go b/codesign/codesign.go index ec425a78..b5007684 100644 --- a/codesign/codesign.go +++ b/codesign/codesign.go @@ -362,6 +362,11 @@ func (m *Manager) prepareCodeSigningWithBitrise(credentials appleauth.Credential return err } + if profileAttachedEntitlements := appLayout.ListProfileAttachedEntitlements(); len(profileAttachedEntitlements) != 0 { + m.logger.Warnf("Can not create profile, due to App Store Connect API limitations for bundle IDs: %v", profileAttachedEntitlements) + m.logger.Warnf("Please use the Manage iOS Code-signing Step with the Profile Template Name input set.") + } + devPortalClient, err := m.devPortalClientFactory.Create(credentials, m.opts.TeamID) if err != nil { return err From 81ca88fa839b1bad8d452d00867ec85d418d8043 Mon Sep 17 00:00:00 2001 From: Laszlo Pusok <7979773+lpusok@users.noreply.github.com> Date: Wed, 11 Jan 2023 11:36:22 +0100 Subject: [PATCH 5/6] Warn if tempalted profile is required --- autocodesign/profiles.go | 7 +++++-- codesign/codesign.go | 5 ----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/autocodesign/profiles.go b/autocodesign/profiles.go index 6d324d06..183ec94e 100644 --- a/autocodesign/profiles.go +++ b/autocodesign/profiles.go @@ -66,9 +66,12 @@ func ensureProfiles(profileClient DevPortalClient, distrType DistributionType, } profileType := platformProfileTypes[distrType] + + profileAttachedEntitlementsByBundleID := app.ListProfileAttachedEntitlements() templateName := distributionToTemplateName[distrType] - if templateName == "" { - log.Debugf("No profile tempalte name provided") + if len(profileAttachedEntitlementsByBundleID) != 0 && templateName == "" { + log.Warnf("Provisioning Profile template name is not set, required by used entitlemets (%v)", profileAttachedEntitlementsByBundleID) + log.Printf("Profile template names can be set only in the Manage iOS Code Signing Step, or by using manually managed profiles with the Certificate and Profile installer Step.") } else { log.Printf("Profile template name: %s", templateName) } diff --git a/codesign/codesign.go b/codesign/codesign.go index b5007684..ec425a78 100644 --- a/codesign/codesign.go +++ b/codesign/codesign.go @@ -362,11 +362,6 @@ func (m *Manager) prepareCodeSigningWithBitrise(credentials appleauth.Credential return err } - if profileAttachedEntitlements := appLayout.ListProfileAttachedEntitlements(); len(profileAttachedEntitlements) != 0 { - m.logger.Warnf("Can not create profile, due to App Store Connect API limitations for bundle IDs: %v", profileAttachedEntitlements) - m.logger.Warnf("Please use the Manage iOS Code-signing Step with the Profile Template Name input set.") - } - devPortalClient, err := m.devPortalClientFactory.Create(credentials, m.opts.TeamID) if err != nil { return err From cf77d4618abf24d8fde388f3b6b4666210e61085 Mon Sep 17 00:00:00 2001 From: Laszlo Pusok <7979773+lpusok@users.noreply.github.com> Date: Wed, 11 Jan 2023 14:21:02 +0100 Subject: [PATCH 6/6] test updated: --- autocodesign/autocodesign_test.go | 65 +++++++++++++++ .../projectmanager/projectmanager_test.go | 79 ------------------- 2 files changed, 65 insertions(+), 79 deletions(-) delete mode 100644 autocodesign/projectmanager/projectmanager_test.go diff --git a/autocodesign/autocodesign_test.go b/autocodesign/autocodesign_test.go index db3f008c..58be4483 100644 --- a/autocodesign/autocodesign_test.go +++ b/autocodesign/autocodesign_test.go @@ -552,3 +552,68 @@ func newClientWithAppIDWithoutAppleSignIn(cert certificateutil.CertificateInfoMo return client } + +func TestAppLayout_ListProfileAttachedEntitlements(t *testing.T) { + tests := []struct { + name string + entitlementsByBundleID map[string]Entitlements + want map[string][]string + }{ + { + name: "no entitlements", + entitlementsByBundleID: map[string]Entitlements{ + "com.bundleid": map[string]interface{}{}, + }, + want: map[string][]string{}, + }, + { + name: "all entitlements supported", + entitlementsByBundleID: map[string]Entitlements{ + "com.bundleid": map[string]interface{}{ + "aps-environment": true, + }, + }, + want: map[string][]string{}, + }, + { + name: "contains unsupported entitlement", + entitlementsByBundleID: map[string]Entitlements{ + "com.bundleid": map[string]interface{}{ + "com.entitlement-ignored": true, + "com.apple.developer.contacts.notes": true, + }, + }, + want: map[string][]string{ + "com.bundleid": {"com.apple.developer.contacts.notes"}, + }, + }, + { + name: "contains unsupported entitlement, multiple bundle IDs", + entitlementsByBundleID: map[string]Entitlements{ + "com.bundleid": map[string]interface{}{ + "aps-environment": true, + "com.apple.developer.carplay-maps": true, + }, + "com.bundleid2": map[string]interface{}{ + "com.entitlement-ignored": true, + "com.apple.developer.contacts.notes": true, + }, + }, + want: map[string][]string{ + "com.bundleid": {"com.apple.developer.carplay-maps"}, + "com.bundleid2": {"com.apple.developer.contacts.notes"}, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + app := AppLayout{ + EntitlementsByArchivableTargetBundleID: tt.entitlementsByBundleID, + } + + got := app.ListProfileAttachedEntitlements() + + require.Equal(t, tt.want, got) + }) + } +} diff --git a/autocodesign/projectmanager/projectmanager_test.go b/autocodesign/projectmanager/projectmanager_test.go deleted file mode 100644 index 1f715fbb..00000000 --- a/autocodesign/projectmanager/projectmanager_test.go +++ /dev/null @@ -1,79 +0,0 @@ -package projectmanager - -import ( - "testing" - - "github.com/bitrise-io/go-xcode/v2/autocodesign" -) - -func TestCanGenerateProfileWithEntitlements(t *testing.T) { - tests := []struct { - name string - entitlementsByBundleID map[string]autocodesign.Entitlements - wantOk bool - wantEntitlement string - wantBundleID string - }{ - { - name: "no entitlements", - entitlementsByBundleID: map[string]autocodesign.Entitlements{ - "com.bundleid": map[string]interface{}{}, - }, - wantOk: true, - wantEntitlement: "", - wantBundleID: "", - }, - { - name: "contains unsupported entitlement", - entitlementsByBundleID: map[string]autocodesign.Entitlements{ - "com.bundleid": map[string]interface{}{ - "com.entitlement-ignored": true, - "com.apple.developer.contacts.notes": true, - }, - }, - wantOk: false, - wantEntitlement: "com.apple.developer.contacts.notes", - wantBundleID: "com.bundleid", - }, - { - name: "contains unsupported entitlement, multiple bundle IDs", - entitlementsByBundleID: map[string]autocodesign.Entitlements{ - "com.bundleid": map[string]interface{}{ - "aps-environment": true, - }, - "com.bundleid2": map[string]interface{}{ - "com.entitlement-ignored": true, - "com.apple.developer.contacts.notes": true, - }, - }, - wantOk: false, - wantEntitlement: "com.apple.developer.contacts.notes", - wantBundleID: "com.bundleid2", - }, - { - name: "all entitlements supported", - entitlementsByBundleID: map[string]autocodesign.Entitlements{ - "com.bundleid": map[string]interface{}{ - "aps-environment": true, - }, - }, - wantOk: true, - wantEntitlement: "", - wantBundleID: "", - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - gotOk, gotEntilement, gotBundleID := CanGenerateProfileWithEntitlements(tt.entitlementsByBundleID) - if gotOk != tt.wantOk { - t.Errorf("CanGenerateProfileWithEntitlements() got = %v, want %v", gotOk, tt.wantOk) - } - if gotEntilement != tt.wantEntitlement { - t.Errorf("CanGenerateProfileWithEntitlements() got1 = %v, want %v", gotEntilement, tt.wantEntitlement) - } - if gotBundleID != tt.wantBundleID { - t.Errorf("CanGenerateProfileWithEntitlements() got2 = %v, want %v", gotBundleID, tt.wantBundleID) - } - }) - } -}