From 6fc5017cd33b62459e1edca9b6e71963ccabf083 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ceyda=20Ak=C4=B1n?= Date: Fri, 9 Oct 2026 09:27:43 +0300 Subject: [PATCH 1/3] [eas-cli] Keep linked capability identifiers when syncing another one The capability update replaces the identifiers linked to a bundle ID, but only the newly linked ones were sent. Adding a second App Group, Merchant ID or iCloud container unlinked the ones that were already linked. Fixes #4445 --- CHANGELOG.md | 1 + .../__tests__/capabilityIdentifiers-test.ts | 29 +++++++++++++++++++ .../ios/appstore/capabilityIdentifiers.ts | 7 +++-- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c53be5232d..3a45a6332e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ This is the log of notable changes to EAS CLI and related packages. ### ๐Ÿ› Bug fixes - [build-tools] Install ffmpeg for Appium simulator sessions. ([#4577](https://github.com/expo/eas-cli/pull/4577) by [@gwdp](https://github.com/gwdp)) +- [eas-cli] Keep already linked App Groups, Merchant IDs and iCloud containers when capability sync links another identifier. ([#PR_NUMBER](https://github.com/expo/eas-cli/pull/PR_NUMBER) by [@ceydaakin](https://github.com/ceydaakin)) ### ๐Ÿงน Chores 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, From 1dc10d625982a4a2f48ea870a5b1e47036e1e286 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ceyda=20Ak=C4=B1n?= Date: Fri, 9 Oct 2026 10:01:55 +0300 Subject: [PATCH 2/3] [eas-cli] Add the pull request number to the changelog entry --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a45a6332e..e113e6f4a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ This is the log of notable changes to EAS CLI and related packages. ### ๐Ÿ› Bug fixes - [build-tools] Install ffmpeg for Appium simulator sessions. ([#4577](https://github.com/expo/eas-cli/pull/4577) by [@gwdp](https://github.com/gwdp)) -- [eas-cli] Keep already linked App Groups, Merchant IDs and iCloud containers when capability sync links another identifier. ([#PR_NUMBER](https://github.com/expo/eas-cli/pull/PR_NUMBER) by [@ceydaakin](https://github.com/ceydaakin)) +- [eas-cli] Keep already linked App Groups, Merchant IDs and iCloud containers when capability sync links another identifier. ([#4584](https://github.com/expo/eas-cli/pull/4584) by [@ceydaakin](https://github.com/ceydaakin)) ### ๐Ÿงน Chores From a75e1eab0bb1e4e582b7e3e14abf81336c546ec9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ceyda=20Ak=C4=B1n?= Date: Thu, 15 Oct 2026 11:46:57 +0300 Subject: [PATCH 3/3] [eas-cli] Move the changelog entry to a changeset --- .changeset/capability-sync-keeps-linked-identifiers.md | 5 +++++ CHANGELOG.md | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 .changeset/capability-sync-keeps-linked-identifiers.md 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/CHANGELOG.md b/CHANGELOG.md index e113e6f4a5..c53be5232d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,6 @@ This is the log of notable changes to EAS CLI and related packages. ### ๐Ÿ› Bug fixes - [build-tools] Install ffmpeg for Appium simulator sessions. ([#4577](https://github.com/expo/eas-cli/pull/4577) by [@gwdp](https://github.com/gwdp)) -- [eas-cli] Keep already linked App Groups, Merchant IDs and iCloud containers when capability sync links another identifier. ([#4584](https://github.com/expo/eas-cli/pull/4584) by [@ceydaakin](https://github.com/ceydaakin)) ### ๐Ÿงน Chores