diff --git a/.changeset/capability-sync-keeps-linked-identifiers.md b/.changeset/capability-sync-keeps-linked-identifiers.md new file mode 100644 index 0000000000..7d48b9c165 --- /dev/null +++ b/.changeset/capability-sync-keeps-linked-identifiers.md @@ -0,0 +1,5 @@ +--- +'eas-cli': patch +--- + +Keep already linked App Groups, Merchant IDs and iCloud containers when capability sync links another identifier. diff --git a/packages/eas-cli/src/credentials/ios/appstore/__tests__/capabilityIdentifiers-test.ts b/packages/eas-cli/src/credentials/ios/appstore/__tests__/capabilityIdentifiers-test.ts index d19a36efd6..37f4e88335 100644 --- a/packages/eas-cli/src/credentials/ios/appstore/__tests__/capabilityIdentifiers-test.ts +++ b/packages/eas-cli/src/credentials/ios/appstore/__tests__/capabilityIdentifiers-test.ts @@ -187,6 +187,35 @@ describe(syncCapabilityIdentifiersForEntitlementsAsync, () => { expect(bundleId.updateBundleIdCapabilityAsync).toHaveBeenCalledTimes(1); }); + it(`keeps already linked capability identifiers when linking another one`, async () => { + const Apple = require('@expo/apple-utils'); + mockCapabilities(Apple); + const bundleId = { + context: {}, + updateBundleIdCapabilityAsync: jest.fn(), + id: 'XXX', + } as any; + + const result = await syncCapabilityIdentifiersForEntitlementsAsync(bundleId, { + 'com.apple.security.application-groups': ['group.expo', 'group.bacon'], + }); + + expect(result).toStrictEqual({ + created: ['group.bacon'], + linked: ['group.bacon'], + }); + expect(bundleId.updateBundleIdCapabilityAsync).toHaveBeenCalledTimes(1); + expect(bundleId.updateBundleIdCapabilityAsync).toHaveBeenLastCalledWith([ + { + capabilityType: 'APP_GROUPS', + option: 'ON', + relationships: { + appGroups: ['XXX-group-1', 'XXX-group-2'], + }, + }, + ]); + }); + it(`doesn't perform duplicate CapabilityModel.getAsync calls`, async () => { const Apple = require('@expo/apple-utils'); mockCapabilities(Apple); diff --git a/packages/eas-cli/src/credentials/ios/appstore/capabilityIdentifiers.ts b/packages/eas-cli/src/credentials/ios/appstore/capabilityIdentifiers.ts index 7eb6a8a217..e0df86f902 100644 --- a/packages/eas-cli/src/credentials/ios/appstore/capabilityIdentifiers.ts +++ b/packages/eas-cli/src/credentials/ios/appstore/capabilityIdentifiers.ts @@ -94,7 +94,8 @@ export async function syncCapabilityIdentifiersForEntitlementsAsync( (remoteLinkedIds?.[CapabilityModel.type] ?? []).map(model => model.id) ); - // A list of server IDs for linking. + // A list of server IDs for linking. The update replaces the linked identifiers, + // so this includes the ones that are already linked. const capabilityIdOpaqueIds: string[] = []; // Iterate through all the local IDs and see if they exist on the server. @@ -106,8 +107,8 @@ export async function syncCapabilityIdentifiersForEntitlementsAsync( if (!alreadyLinkedOpaqueIds.has(remoteIdModel.id)) { // Link the existing identifier to this bundle. linkedIds.push(remoteIdModel.attributes.identifier); - capabilityIdOpaqueIds.push(remoteIdModel.id); } + capabilityIdOpaqueIds.push(remoteIdModel.id); continue; } @@ -133,7 +134,7 @@ export async function syncCapabilityIdentifiersForEntitlementsAsync( capabilityIdOpaqueIds.push(remoteIdModel.id); } - if (capabilityIdOpaqueIds.length) { + if (capabilityIdOpaqueIds.some(id => !alreadyLinkedOpaqueIds.has(id))) { updateRequest.push({ capabilityType: classifier.capability, option: CapabilityTypeOption.ON,