Repository: wordpress-mobile/WordPress-iOS
Pull request #24518: Reset Modules as an Xcode local package with tests in CI
Author: login: mokagio
Labels: name: Testing
description: Unit and UI Tests and Tooling
Created: 2025-05-05T06:04:44Z | Merged: 2025-05-12T19:46:17Z

## Description

https://github.com/wordpress-mobile/WordPress-iOS/pull/24511 successfully addressed the issue of duplicated packages in the target selection.

Unfortunately, it resulted in all local packages (those from `Modules/` that is) no longer being accessible to the unit tests runner—see internal discussion in p1746169066574499/1745343713.430699-slack-C08HQR4C2TS

This PR propose a different fix, achieved by re-adding `Modules/` **as a local _package_ not a package _dependency_**, following the instructions from https://developer.apple.com/documentation/xcode/organizing-your-code-with-local-packages.

This setup maintains the single result in the target search...

<img width="495" alt="image" src="https://github.com/user-attachments/assets/ad8d1b7a-cd2d-4204-b9b8-40adeeb0e512" />

...while also allowing for `Modules/` to run as dedicated schemes or as part of a test plan

<img width="1051" alt="image" src="https://github.com/user-attachments/assets/fb682cbc-b4e6-43d8-b154-ce100f1df4e3" />

<img width="710" alt="image" src="https://github.com/user-attachments/assets/62b449ce-46a1-4058-a091-90dc04736529" />

Also notice, we have so many tests (and warnings when running them!) that the logs don't show the first tests that run, but if you check the XML report, you'll see that indeed we are running all previously disabled tests

![image](https://github.com/user-attachments/assets/bb7bd2a2-c564-431d-a0cd-077fcaeae70e)


## Next steps

- Rename `WordPressUnitTests.xctestplan` to `Keystone.xctestplan`—to do in dedicated PR to avoid diff noise here
- Ensure all module targets that have tests run as part as `Keystone.xctestplan`
- Add dedicated schemes for focused package development

---

https://linear.app/a8c/issue/AINFRA-428/investigate-wjr-setup-that-addresses-duplicated-modules-while


Diff:
diff --git a/.buildkite/commands/complete-code-freeze.sh b/.buildkite/commands/complete-code-freeze.sh
index 40653d10c534..9297d9e4d298 100755
--- a/.buildkite/commands/complete-code-freeze.sh
+++ b/.buildkite/commands/complete-code-freeze.sh
@@ -12,11 +12,7 @@ source use-bot-for-git
 
 .buildkite/commands/checkout-release-branch.sh "$RELEASE_NUMBER"
 
-echo '--- :ruby: Setup Ruby tools'
-install_gems
-
-echo "--- :swift: Set up Swift Packages"
-install_swiftpm_dependencies
+"$(dirname "${BASH_SOURCE[0]}")/shared-set-up.sh"
 
 echo '--- :closed_lock_with_key: Access secrets'
 bundle exec fastlane run configure_apply
diff --git a/.buildkite/commands/shared-set-up.sh b/.buildkite/commands/shared-set-up.sh
index 15a74d84b996..1e04425db6f8 100755
--- a/.buildkite/commands/shared-set-up.sh
+++ b/.buildkite/commands/shared-set-up.sh
@@ -3,8 +3,12 @@
 echo "--- :rubygems: Setting up Gems"
 install_gems
 
+# The push/pop is workaround for tooling not supporting a Package.swift path.
+# Note that neither ours nor Apple's tooling does.
+pushd "$(dirname "${BASH_SOURCE[0]}")/../../Modules"
 echo "--- :swift: Setting up Swift Packages"
 install_swiftpm_dependencies
+popd
 
 echo "--- :xcode: Fetch XCFrameworks"
 rake dependencies
diff --git a/.gitignore b/.gitignore
index b9ef88a5e0e6..9924e15ba219 100644
--- a/.gitignore
+++ b/.gitignore
@@ -125,12 +125,6 @@ WordPress/InfoPlist-internal.h
 # and assume no local copy would have generated the Pods.
 Pods/
 
-# Modules — Where the Swift packages that make up the modular app live
-#
-# Ignore the Package.resolved file. The packages source of truth is the
-# resolved file generated by the Xcode workspace.
-Modules/Package.resolved
-
 # While we depend on gutenberg-mobile, we download its XCFrameworks in
 # WordPress/Frameworks
 WordPress/Frameworks/*.xcframework
diff --git a/WordPress.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Modules/Package.resolved
similarity index 88%
rename from WordPress.xcworkspace/xcshareddata/swiftpm/Package.resolved
rename to Modules/Package.resolved
index cb31731be9ca..e16ac268b03a 100644
--- a/WordPress.xcworkspace/xcshareddata/swiftpm/Package.resolved
+++ b/Modules/Package.resolved
@@ -1,13 +1,13 @@
 {
-  "originHash" : "4d299ae36ff454e0e3ec59a9c04557210efa32d8b96b189963ad0f3ffebb3e70",
+  "originHash" : "fe094f15c8e18dab512a2ddf88e08b4c895c60964ac1158c031ee731381eda34",
   "pins" : [
     {
       "identity" : "alamofire",
       "kind" : "remoteSourceControl",
       "location" : "https://github.com/Alamofire/Alamofire",
       "state" : {
-        "revision" : "f455c2975872ccd2d9c81594c658af65716e9b9a",
-        "version" : "5.9.1"
+        "revision" : "513364f870f6bfc468f9d2ff0a95caccc10044c5",
+        "version" : "5.10.2"
       }
     },
     {
@@ -60,8 +60,7 @@
       "kind" : "remoteSourceControl",
       "location" : "https://github.com/Automattic/color-studio",
       "state" : {
-        "branch" : "trunk",
-        "revision" : "bdcf795bc2c191bd45bd6c24734030257becd050"
+        "revision" : "bf141adc75e2769eb469a3e095bdc93dc30be8de"
       }
     },
     {
@@ -69,8 +68,8 @@
       "kind" : "remoteSourceControl",
       "location" : "https://github.com/zendesk/commonui_sdk_ios",
       "state" : {
-        "revision" : "8729e7f4e316b46f6d33f046e663b6eedfe9955a",
-        "version" : "9.0.1"
+        "revision" : "8c1ab48a4a04637c42afc46d6b45b57c26ac05aa",
+        "version" : "9.0.2"
       }
     },
     {
@@ -78,8 +77,8 @@
       "kind" : "remoteSourceControl",
       "location" : "https://github.com/zendesk/core_sdk_ios",
       "state" : {
-        "revision" : "8163d4d67f3aa8954467aa8191ee13cb4f1a2b9e",
-        "version" : "5.0.3"
+        "revision" : "4d676f214e48017d102cd499d5f453c5cf6d9ef2",
+        "version" : "5.0.4"
       }
     },
     {
@@ -87,8 +86,8 @@
       "kind" : "remoteSourceControl",
       "location" : "https://github.com/mattgallagher/CwlCatchException.git",
       "state" : {
-        "revision" : "35f9e770f54ce62dd8526470f14c6e137cef3eea",
-        "version" : "2.1.1"
+        "revision" : "07b2ba21d361c223e25e3c1e924288742923f08c",
+        "version" : "2.2.1"
       }
     },
     {
@@ -96,8 +95,8 @@
       "kind" : "remoteSourceControl",
       "location" : "https://github.com/mattgallagher/CwlPreconditionTesting.git",
       "state" : {
-        "revision" : "c21f7bab5ca8eee0a9998bbd17ca1d0eb45d4688",
-        "version" : "2.1.0"
+        "revision" : "0139c665ebb45e6a9fbdb68aabfd7c39f3fe0071",
+        "version" : "2.2.2"
       }
     },
     {
@@ -168,8 +167,8 @@
       "kind" : "remoteSourceControl",
       "location" : "https://github.com/airbnb/lottie-ios",
       "state" : {
-        "revision" : "f522990668c2f9132323a2e68d924c7dcb9130b4",
-        "version" : "4.4.0"
+        "revision" : "047aa81b77adcbf583a966dfef620d17650cc656",
+        "version" : "4.5.1"
       }
     },
     {
@@ -178,7 +177,7 @@
       "location" : "https://github.com/wordpress-mobile/MediaEditor-iOS",
       "state" : {
         "branch" : "task/spm-support",
-        "revision" : "4f3fe298a95d1de81099f8c9e5612e0c59c9bf53"
+        "revision" : "e9f74b21276d5cd1cb94ee1c09cc060b23187832"
       }
     },
     {
@@ -186,8 +185,8 @@
       "kind" : "remoteSourceControl",
       "location" : "https://github.com/zendesk/messaging_sdk_ios",
       "state" : {
-        "revision" : "4dbb16d26b90452c1d41cba8e8dc81a1bcea7f1e",
-        "version" : "6.0.1"
+        "revision" : "0f81007fe9c9467bc583040f3343b205311cebfd",
+        "version" : "6.0.2"
       }
     },
     {
@@ -195,8 +194,8 @@
       "kind" : "remoteSourceControl",
       "location" : "https://github.com/zendesk/messagingapi_sdk_ios",
       "state" : {
-        "revision" : "2f21e014a1f284edf484faf39b2b6fe377ec8c64",
-        "version" : "6.0.0"
+        "revision" : "f86020a681e28a7bfae9e2445eb027d37dc5d5f5",
+        "version" : "6.0.1"
       }
     },
     {
@@ -222,7 +221,6 @@
       "kind" : "remoteSourceControl",
       "location" : "https://github.com/wordpress-mobile/NSURL-IDN",
       "state" : {
-        "branch" : "cmm-322-remove-plus-from-name",
         "revision" : "b34794c9a3f32312e1593d4a3d120572afa0d010"
       }
     },
@@ -293,8 +291,8 @@
       "kind" : "remoteSourceControl",
       "location" : "https://github.com/zendesk/support_providers_sdk_ios",
       "state" : {
-        "revision" : "16da780d8a0aa905b3935eee7836b9a0ee276597",
-        "version" : "8.0.3"
+        "revision" : "b8194243297eaab61a92138a1dc5872bce358346",
+        "version" : "8.0.4"
       }
     },
     {
@@ -302,8 +300,8 @@
       "kind" : "remoteSourceControl",
       "location" : "https://github.com/zendesk/support_sdk_ios",
       "state" : {
-        "revision" : "44cf26111bf0bc608a2474578b3d506793eef483",
-        "version" : "8.0.3"
+        "revision" : "6b5f6d2ffc92c10d38cb9c716ae37b2832230c89",
+        "version" : "8.0.4"
       }
     },
     {
@@ -329,8 +327,8 @@
       "kind" : "remoteSourceControl",
       "location" : "https://github.com/apple/swift-log",
       "state" : {
-        "revision" : "e97a6fcb1ab07462881ac165fdbb37f067e205d5",
-        "version" : "1.5.4"
+        "revision" : "96a2f8a0fa41e9e09af4585e2724c4e825410b91",
+        "version" : "1.6.2"
       }
     },
     {
@@ -356,8 +354,8 @@
       "kind" : "remoteSourceControl",
       "location" : "https://github.com/buildkite/test-collector-swift",
       "state" : {
-        "revision" : "77c7f492f5c1c9ca159f73d18f56bbd1186390b0",
-        "version" : "0.3.0"
+        "revision" : "631a2400dbe876141a3ef8c7400885907fec7f89",
+        "version" : "0.4.1"
       }
     },
     {
@@ -392,7 +390,6 @@
       "kind" : "remoteSourceControl",
       "location" : "https://github.com/wordpress-mobile/WordPressKit-iOS",
       "state" : {
-        "branch" : "wpios-edition",
         "revision" : "5bc08764d2025e21685816065f611e884c8672d1"
       }
     },
diff --git a/Modules/Package.swift b/Modules/Package.swift
index 0d88e290f045..b8b352da1f8c 100644
--- a/Modules/Package.swift
+++ b/Modules/Package.swift
@@ -48,12 +48,18 @@ let package = Package(
         .package(url: "https://github.com/wordpress-mobile/MediaEditor-iOS", branch: "task/spm-support"),
         .package(url: "https://github.com/wordpress-mobile/NSObject-SafeExpectations", from: "0.0.6"),
         .package(url: "https://github.com/wordpress-mobile/NSURL-IDN", revision: "b34794c9a3f32312e1593d4a3d120572afa0d010"),
-        .package(url: "https://github.com/wordpress-mobile/WordPressKit-iOS", branch: "wpios-edition"),
+        .package(
+            url: "https://github.com/wordpress-mobile/WordPressKit-iOS",
+            revision: "5bc08764d2025e21685816065f611e884c8672d1" // see wpios-edition branch
+        ),
         .package(url: "https://github.com/zendesk/support_sdk_ios", from: "8.0.3"),
         // We can't use wordpress-rs branches nor commits here. Only tags work.
         .package(url: "https://github.com/Automattic/wordpress-rs", revision: "alpha-20250505"),
         .package(url: "https://github.com/wordpress-mobile/GutenbergKit", from: "0.2.0"),
-        .package(url: "https://github.com/Automattic/color-studio", branch: "trunk"),
+        .package(
+            url: "https://github.com/Automattic/color-studio",
+            revision: "bf141adc75e2769eb469a3e095bdc93dc30be8de"
+        ),
         .package(url: "https://github.com/wordpress-mobile/AztecEditor-iOS", from: "1.20.0"),
     ],
     targets: XcodeSupport.targets + [
@@ -168,7 +174,12 @@ let package = Package(
         ),
         .testTarget(name: "JetpackStatsWidgetsCoreTests", dependencies: [.target(name: "JetpackStatsWidgetsCore")], swiftSettings: [.swiftLanguageMode(.v5)]),
         .testTarget(name: "DesignSystemTests", dependencies: [.target(name: "DesignSystem")], swiftSettings: [.swiftLanguageMode(.v5)]),
-        .testTarget(name: "WordPressFluxTests", dependencies: ["WordPressFlux"], swiftSettings: [.swiftLanguageMode(.v5)]),
+        .testTarget(
+            name: "WordPressFluxTests",
+            dependencies: ["WordPressFlux"],
+            exclude: ["WordPressFluxTests.xctestplan"],
+            swiftSettings: [.swiftLanguageMode(.v5)]
+        ),
         .testTarget(name: "AsyncImageKitTests", dependencies: [
             .target(name: "AsyncImageKit"),
             .target(name: "WordPressTesting"),
diff --git a/Modules/Tests/WordPressFluxTests/WordPressFluxTests.xctestplan b/Modules/Tests/WordPressFluxTests/WordPressFluxTests.xctestplan
new file mode 100644
index 000000000000..5dd4d0071652
--- /dev/null
+++ b/Modules/Tests/WordPressFluxTests/WordPressFluxTests.xctestplan
@@ -0,0 +1,24 @@
+{
+  "configurations" : [
+    {
+      "id" : "92A65F35-8051-4F5F-B68A-1802B2E06105",
+      "name" : "Test Scheme Action",
+      "options" : {
+
+      }
+    }
+  ],
+  "defaultOptions" : {
+    "codeCoverage" : false
+  },
+  "testTargets" : [
+    {
+      "target" : {
+        "containerPath" : "container:",
+        "identifier" : "WordPressFluxTests",
+        "name" : "WordPressFluxTests"
+      }
+    }
+  ],
+  "version" : 1
+}
diff --git a/Tests/KeystoneTests/WordPressUnitTests.xctestplan b/Tests/KeystoneTests/WordPressUnitTests.xctestplan
index 533e46b6ccd9..5fbff54d114f 100644
--- a/Tests/KeystoneTests/WordPressUnitTests.xctestplan
+++ b/Tests/KeystoneTests/WordPressUnitTests.xctestplan
@@ -32,7 +32,6 @@
   },
   "testTargets" : [
     {
-      "enabled" : false,
       "target" : {
         "containerPath" : "container:..\/Modules",
         "identifier" : "AsyncImageKitTests",
@@ -40,7 +39,6 @@
       }
     },
     {
-      "enabled" : false,
       "target" : {
         "containerPath" : "container:WordPress.xcodeproj",
         "identifier" : "4AD953BA2C21451700D0EEFA",
@@ -62,7 +60,6 @@
       }
     },
     {
-      "enabled" : false,
       "target" : {
         "containerPath" : "container:..\/Modules",
         "identifier" : "WordPressUIUnitTests",
@@ -70,7 +67,6 @@
       }
     },
     {
-      "enabled" : false,
       "target" : {
         "containerPath" : "container:..\/Modules",
         "identifier" : "WordPressSharedTests",
@@ -78,7 +74,6 @@
       }
     },
     {
-      "enabled" : false,
       "target" : {
         "containerPath" : "container:..\/Modules",
         "identifier" : "JetpackStatsWidgetsCoreTests",
@@ -86,7 +81,6 @@
       }
     },
     {
-      "enabled" : false,
       "target" : {
         "containerPath" : "container:..\/Modules",
         "identifier" : "WordPressFluxTests",
@@ -94,7 +88,6 @@
       }
     },
     {
-      "enabled" : false,
       "target" : {
         "containerPath" : "container:..\/Modules",
         "identifier" : "WordPressSharedObjCTests",
diff --git a/WordPress/WordPress.xcodeproj/project.pbxproj b/WordPress/WordPress.xcodeproj/project.pbxproj
index 5df5b276a969..57f829d04d52 100644
--- a/WordPress/WordPress.xcodeproj/project.pbxproj
+++ b/WordPress/WordPress.xcodeproj/project.pbxproj
@@ -804,6 +804,7 @@
 		3F9DD3F62CC214BF00DF1760 /* Common.debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Common.debug.xcconfig; sourceTree = "<group>"; };
 		3F9DD3F72CC2188400DF1760 /* Common.alpha.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Common.alpha.xcconfig; sourceTree = "<group>"; };
 		3FA640652670CEFE0064401E /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Platforms/iPhoneOS.platform/Developer/Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
+		3FD4B20E2DCC468200781DFA /* Modules */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = Modules; path = ../Modules; sourceTree = SOURCE_ROOT; };
 		406A0EEF224D39C50016AD6A /* Flags.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Flags.xcassets; sourceTree = "<group>"; };
 		433840C622C2BA5B00CB13F8 /* AppImages.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = AppImages.xcassets; path = Resources/AppImages.xcassets; sourceTree = "<group>"; };
 		4A690C142BA790BC00A8E0C5 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
@@ -1606,6 +1607,7 @@
 		29B97314FDCFA39411CA2CEA /* CustomTemplate */ = {
 			isa = PBXGroup;
 			children = (
+				3FD4B20E2DCC468200781DFA /* Modules */,
 				0C5C46FB2D98395300F2CD55 /* Sources */,
 				0C5A19CB2D9B07E700C25301 /* Tests */,
 				F14B5F6F208E648200439554 /* config */,
@@ -2705,7 +2707,6 @@
 			);
 			mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */;
 			packageReferences = (
-				0C8095952DC2A4B9008DFC2F /* XCLocalSwiftPackageReference "../Modules" */,
 			);
 			preferredProjectObjectVersion = 77;
 			productRefGroup = 19C28FACFE9D520D11CA2CBB /* Products */;
@@ -7040,13 +7041,6 @@
 		};
 /* End XCConfigurationList section */
 
-/* Begin XCLocalSwiftPackageReference section */
-		0C8095952DC2A4B9008DFC2F /* XCLocalSwiftPackageReference "../Modules" */ = {
-			isa = XCLocalSwiftPackageReference;
-			relativePath = ../Modules;
-		};
-/* End XCLocalSwiftPackageReference section */
-
 /* Begin XCSwiftPackageProductDependency section */
 		0C2155A52C39A24D00EFE2C0 /* XcodeTarget_UITests */ = {
 			isa = XCSwiftPackageProductDependency;
diff --git a/WordPress/WordPress.xcodeproj/xcshareddata/xcschemes/OCLint.xcscheme b/WordPress/WordPress.xcodeproj/xcshareddata/xcschemes/OCLint.xcscheme
deleted file mode 100644
index 204b88ed5dab..000000000000
--- a/WordPress/WordPress.xcodeproj/xcshareddata/xcschemes/OCLint.xcscheme
+++ /dev/null
@@ -1,76 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<Scheme
-   LastUpgradeVersion = "1540"
-   version = "1.3">
-   <BuildAction
-      parallelizeBuildables = "YES"
-      buildImplicitDependencies = "YES">
-      <BuildActionEntries>
-         <BuildActionEntry
-            buildForTesting = "YES"
-            buildForRunning = "YES"
-            buildForProfiling = "YES"
-            buildForArchiving = "YES"
-            buildForAnalyzing = "YES">
-            <BuildableReference
-               BuildableIdentifier = "primary"
-               BlueprintIdentifier = "A2795807198819DE0031C6A3"
-               BuildableName = "OCLint"
-               BlueprintName = "OCLint"
-               ReferencedContainer = "container:WordPress.xcodeproj">
-            </BuildableReference>
-         </BuildActionEntry>
-      </BuildActionEntries>
-   </BuildAction>
-   <TestAction
-      buildConfiguration = "Debug"
-      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
-      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
-      shouldUseLaunchSchemeArgsEnv = "YES">
-      <Testables>
-      </Testables>
-   </TestAction>
-   <LaunchAction
-      buildConfiguration = "Debug"
-      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
-      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
-      launchStyle = "0"
-      useCustomWorkingDirectory = "NO"
-      ignoresPersistentStateOnLaunch = "NO"
-      debugDocumentVersioning = "YES"
-      debugServiceExtension = "internal"
-      allowLocationSimulation = "YES">
-      <MacroExpansion>
-         <BuildableReference
-            BuildableIdentifier = "primary"
-            BlueprintIdentifier = "A2795807198819DE0031C6A3"
-            BuildableName = "OCLint"
-            BlueprintName = "OCLint"
-            ReferencedContainer = "container:WordPress.xcodeproj">
-         </BuildableReference>
-      </MacroExpansion>
-   </LaunchAction>
-   <ProfileAction
-      buildConfiguration = "Release"
-      shouldUseLaunchSchemeArgsEnv = "YES"
-      savedToolIdentifier = ""
-      useCustomWorkingDirectory = "NO"
-      debugDocumentVersioning = "YES">
-      <MacroExpansion>
-         <BuildableReference
-            BuildableIdentifier = "primary"
-            BlueprintIdentifier = "A2795807198819DE0031C6A3"
-            BuildableName = "OCLint"
-            BlueprintName = "OCLint"
-            ReferencedContainer = "container:WordPress.xcodeproj">
-         </BuildableReference>
-      </MacroExpansion>
-   </ProfileAction>
-   <AnalyzeAction
-      buildConfiguration = "Debug">
-   </AnalyzeAction>
-   <ArchiveAction
-      buildConfiguration = "Release"
-      revealArchiveInOrganizer = "YES">
-   </ArchiveAction>
-</Scheme>


Reviews:
user: login: mokagio
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-05T08:20:32Z
user: login: mokagio
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-05T08:22:33Z
user: login: mokagio
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-05T08:25:21Z
user: login: kean
body: This looks good. Let's switch back to the standard "drag-n-drop" approach. I left a couple of small comments.
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-07T13:46:33Z
user: login: mokagio
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-08T06:33:25Z
user: login: mokagio
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-08T06:33:53Z
user: login: kean
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-08T13:56:04Z
user: login: kean
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-08T14:15:04Z
user: login: mokagio
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-09T01:33:35Z
user: login: mokagio
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-09T01:36:56Z
user: login: mokagio
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-09T06:22:20Z
user: login: kean
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-12T19:22:42Z

Review comments:
diff_hunk: @@ -169,7 +170,12 @@ let package = Package(
         ),
         .testTarget(name: "JetpackStatsWidgetsCoreTests", dependencies: [.target(name: "JetpackStatsWidgetsCore")], swiftSettings: [.swiftLanguageMode(.v5)]),
         .testTarget(name: "DesignSystemTests", dependencies: [.target(name: "DesignSystem")], swiftSettings: [.swiftLanguageMode(.v5)]),
-        .testTarget(name: "WordPressFluxTests", dependencies: ["WordPressFlux"], swiftSettings: [.swiftLanguageMode(.v5)]),
+        .testTarget(
+            name: "WordPressFluxTests",
+            dependencies: ["WordPressFlux"],
+            exclude: ["WordPressFluxTests.xctestplan"],
+            swiftSettings: [.swiftLanguageMode(.v5)]
+        ),
path: Modules/Package.swift
user: login: mokagio
body: I added this to see how `WordPressFluxTests` would run tests with standalone scheme.

Interestingly, I tried using a copy-paste friendly `exclude: ["*.xctestplan"],` pattern, but it failed to find the file.
created_at: 2025-05-05T08:20:31Z
author_association: CONTRIBUTOR
diff_hunk: @@ -7085,13 +7084,6 @@
 		};
 /* End XCConfigurationList section */
 
-/* Begin XCLocalSwiftPackageReference section */
-		0C8095952DC2A4B9008DFC2F /* XCLocalSwiftPackageReference "../Modules" */ = {
-			isa = XCLocalSwiftPackageReference;
-			relativePath = ../Modules;
-		};
-/* End XCLocalSwiftPackageReference section */
-
path: WordPress/WordPress.xcodeproj/project.pbxproj
user: login: mokagio
body: I think the difference between this and the previous setup (pre https://github.com/wordpress-mobile/WordPress-iOS/pull/24511) is that we no longer have _any_ local swift package reference as a dependency for WordPress. 

My guess is that, whichever way it ended up like that, the duplicated reference—as a local module in the workspace and as a package reference—is what resulted in the duplicated entries shown in the #24511 description.
created_at: 2025-05-05T08:22:33Z
author_association: CONTRIBUTOR
diff_hunk: @@ -169,7 +170,12 @@ let package = Package(
         ),
         .testTarget(name: "JetpackStatsWidgetsCoreTests", dependencies: [.target(name: "JetpackStatsWidgetsCore")], swiftSettings: [.swiftLanguageMode(.v5)]),
         .testTarget(name: "DesignSystemTests", dependencies: [.target(name: "DesignSystem")], swiftSettings: [.swiftLanguageMode(.v5)]),
-        .testTarget(name: "WordPressFluxTests", dependencies: ["WordPressFlux"], swiftSettings: [.swiftLanguageMode(.v5)]),
+        .testTarget(
+            name: "WordPressFluxTests",
+            dependencies: ["WordPressFlux"],
+            exclude: ["WordPressFluxTests.xctestplan"],
+            swiftSettings: [.swiftLanguageMode(.v5)]
+        ),
path: Modules/Package.swift
user: login: mokagio
body: My autogenerated scheme picks up the test plan:

<img width="956" alt="image" src="https://github.com/user-attachments/assets/f998752d-c899-42fc-81e0-c08c123fb8d1" />

However, I got an unlock prompt when I edited it (but no `xcsheme` change in the project, possibly because the scheme might be in `Modules/.swiftpm`) so I'd be curious to know if you see it too...


created_at: 2025-05-05T08:25:21Z
author_association: CONTRIBUTOR
diff_hunk: @@ -6,6 +6,7 @@ let package = Package(
     name: "Modules",
     platforms: [
         .iOS(.v16),
+        .macOS(.v14), // Here just to avoid errors when building directly with `swift build`
path: Modules/Package.swift
user: login: kean
body: Is this addition necessary? Most of our packages do not support macOS and won't compile with it as a target. 
created_at: 2025-05-07T13:42:53Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,6 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Workspace
    version = "1.0">
+   <FileRef
path: WordPress.xcworkspace/contents.xcworkspacedata
user: login: kean
body: Let's add `Modules` to a project and not a workspace. We we going to remove the workspace.
created_at: 2025-05-07T13:43:51Z
author_association: CONTRIBUTOR
diff_hunk: @@ -6,6 +6,7 @@ let package = Package(
     name: "Modules",
     platforms: [
         .iOS(.v16),
+        .macOS(.v14), // Here just to avoid errors when building directly with `swift build`
path: Modules/Package.swift
user: login: mokagio
body: I find it handy to have just so `swift build` throws legitimate errors with the code rather than with the versions. 

In particular, it was necessary to run the WordPressFlux tests via `swift test`. However, as I try to reproduce, I can't get past some UIKit errors, which I find odd when focused on WordPressFlux, but don't have bandwidth to investigate.

Removed it.
created_at: 2025-05-08T06:33:25Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,6 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Workspace
    version = "1.0">
+   <FileRef
path: WordPress.xcworkspace/contents.xcworkspacedata
user: login: mokagio
body: Done.
created_at: 2025-05-08T06:33:53Z
author_association: CONTRIBUTOR
diff_hunk: @@ -6,6 +6,7 @@ let package = Package(
     name: "Modules",
     platforms: [
         .iOS(.v16),
+        .macOS(.v14), // Here just to avoid errors when building directly with `swift build`
path: Modules/Package.swift
user: login: kean
body: Thanks! Yeah, I'd remove it since it doesn't support macOS.
created_at: 2025-05-08T13:56:04Z
author_association: CONTRIBUTOR
diff_hunk: @@ -125,12 +125,6 @@ WordPress/InfoPlist-internal.h
 # and assume no local copy would have generated the Pods.
 Pods/
 
-# Modules — Where the Swift packages that make up the modular app live
-#
-# Ignore the Package.resolved file. The packages source of truth is the
-# resolved file generated by the Xcode workspace.
-Modules/Package.resolved
path: .gitignore
user: login: kean
body: I thought you had to use `...ace/xcshareddata/swiftpm/Package.resolved` managed by Xcode? `Modules/Package.resolved` isn't, or is it? How did you get it to work? When you open the Xcode project, does it use pins from `Modules/Package.resolved`?

```
...ace/xcshareddata/swiftpm/Package.resolved → Modules/Package.resolved
```
created_at: 2025-05-08T14:15:03Z
author_association: CONTRIBUTOR
diff_hunk: @@ -125,12 +125,6 @@ WordPress/InfoPlist-internal.h
 # and assume no local copy would have generated the Pods.
 Pods/
 
-# Modules — Where the Swift packages that make up the modular app live
-#
-# Ignore the Package.resolved file. The packages source of truth is the
-# resolved file generated by the Xcode workspace.
-Modules/Package.resolved
path: .gitignore
user: login: mokagio
body: Apologies @kean this change surprised me a bit and I should have preempted your question writing about it.

## Before

`Modules` was part of the workspace. When Xcode detected changes in `Modules/Package.swift`, it triggered the packages resolution and updated the resolved file in the workspace `xcshareddata` folder.

## After

`Modules` is part of the project, but is not a dependency of the project:

![image](https://github.com/user-attachments/assets/9abdaa78-f7cd-4b6f-97d3-e0b98cc9acbd)

When Xcode detects a change in `Modules/Package.swift`, it triggers the packages resolution and updates `Modules/Package.resolved`.

I guess that if we were to add additional package dependencies _to the project_ Xcode would then re-introduce the  workspace resolved file.
created_at: 2025-05-09T01:33:34Z
author_association: CONTRIBUTOR
diff_hunk: @@ -125,12 +125,6 @@ WordPress/InfoPlist-internal.h
 # and assume no local copy would have generated the Pods.
 Pods/
 
-# Modules — Where the Swift packages that make up the modular app live
-#
-# Ignore the Package.resolved file. The packages source of truth is the
-# resolved file generated by the Xcode workspace.
-Modules/Package.resolved
path: .gitignore
user: login: mokagio
body: > When Xcode detects a change in Modules/Package.swift, it triggers the packages resolution and updates Modules/Package.resolved.

I verified this by switching `color-studio` from pointing to a branch to a commit. The screenshot below shows Xcode highlighting the change in the gutter and the package resolution running.

![image](https://github.com/user-attachments/assets/01846ab0-6031-4e30-8238-915d0775ce38)

35e360bb81 tracks the changes and the `.resolved` update.
created_at: 2025-05-09T01:36:56Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,6 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Workspace
    version = "1.0">
+   <FileRef
path: WordPress.xcworkspace/contents.xcworkspacedata
user: login: mokagio
body: > We we going to remove the workspace.

I started looking at it https://github.com/wordpress-mobile/WordPress-iOS/pull/24534
created_at: 2025-05-09T06:22:20Z
author_association: CONTRIBUTOR

PR comments:
user: login: dangermattic
created_at: 2025-05-05T06:05:18Z
body: <!--
  0 Errors
  1 Warning: <code>Modules/Package.swift</c...
  0 Messages
  0 Markdowns
-->
<table>
  <thead>
    <tr>
      <th width="50"></th>
      <th width="100%" data-danger-table="true" data-kind="Warning">
          1 Warning
      </th>
     </tr>
  </thead>
  <tbody>
    <tr>
      <td>:warning:</td>
      <td data-sticky="false"><code>Modules/Package.swift</code> was changed without updating its corresponding <code>Package.resolved</code>. Please resolve the Swift packages as appropriate to your project setup (e.g. in Xcode or by running <code>swift package resolve</code>).</td>
    </tr>
  </tbody>
</table>

<p align="right" data-meta="generated_by_pr-check">
  Generated by :no_entry_sign: <a href="https://danger.systems/">Danger</a>
</p>

author_association: COLLABORATOR
user: login: wpmobilebot
created_at: 2025-05-05T06:15:43Z
body: <!-- REUSE_ID: prototype-build-link-1:124902176124:ios:121c494b82f283ec1620f9 -->

<details><summary><img align='top' src='https://raw.githubusercontent.com/buildkite/emojis/main/img-buildkite-64/jetpack.png' width='20px' alt='App Icon' />📲 You can test the changes from this Pull Request in <b>Jetpack</b> by scanning the QR code below to install the corresponding build.</summary>
<table>
<tr>
  <td rowspan='7' width='260px'><img src='https://api.qrserver.com/v1/create-qr-code/?size=500x500&qzone=4&data=https%3A%2F%2Fappdistribution.firebase.google.com%2Ftesterapps%2F1%3A124902176124%3Aios%3A121c494b82f283ec1620f9%2Freleases%2F4ou60b6lvr0io%3Futm_source%3Dfastlane' width='250' height='250' /></td>
  <td><b>App Name</b></td><td>Jetpack</td>
</tr>
<tr><td><b>Configuration</b></td><td>Release-Alpha</td></tr>
<tr><td><b>Build Number</b></td><td><code>27638</code></td></tr>
<tr><td><b>Version</b></td><td><code>PR #24518</code></td></tr>
<tr><td><b>Bundle ID</b></td><td><code>com.jetpack.alpha</code></td></tr>
<tr><td><b>Commit</b></td><td>35e360bb81fb0967ed20b2b02727da28679473f0</td></tr>
<tr><td><b>Installation URL</b></td><td><a href='https://appdistribution.firebase.google.com/testerapps/1:124902176124:ios:121c494b82f283ec1620f9/releases/4ou60b6lvr0io?utm_source=fastlane'>4ou60b6lvr0io</a></td></tr>
</table>
<em>Automatticians: You can use our internal self-serve MC tool to give yourself access to those builds if needed.</em>
</details>

author_association: CONTRIBUTOR
user: login: wpmobilebot
created_at: 2025-05-05T06:15:44Z
body: <!-- REUSE_ID: prototype-build-link-1:124902176124:ios:ff9714d0b53aac821620f9 -->

<details><summary><img align='top' src='https://raw.githubusercontent.com/buildkite/emojis/main/img-buildkite-64/wordpress.png' width='20px' alt='App Icon' />📲 You can test the changes from this Pull Request in <b>WordPress</b> by scanning the QR code below to install the corresponding build.</summary>
<table>
<tr>
  <td rowspan='7' width='260px'><img src='https://api.qrserver.com/v1/create-qr-code/?size=500x500&qzone=4&data=https%3A%2F%2Fappdistribution.firebase.google.com%2Ftesterapps%2F1%3A124902176124%3Aios%3Aff9714d0b53aac821620f9%2Freleases%2F7q8s5eep52dho%3Futm_source%3Dfastlane' width='250' height='250' /></td>
  <td><b>App Name</b></td><td>WordPress</td>
</tr>
<tr><td><b>Configuration</b></td><td>Release-Alpha</td></tr>
<tr><td><b>Build Number</b></td><td><code>27638</code></td></tr>
<tr><td><b>Version</b></td><td><code>PR #24518</code></td></tr>
<tr><td><b>Bundle ID</b></td><td><code>org.wordpress.alpha</code></td></tr>
<tr><td><b>Commit</b></td><td>35e360bb81fb0967ed20b2b02727da28679473f0</td></tr>
<tr><td><b>Installation URL</b></td><td><a href='https://appdistribution.firebase.google.com/testerapps/1:124902176124:ios:ff9714d0b53aac821620f9/releases/7q8s5eep52dho?utm_source=fastlane'>7q8s5eep52dho</a></td></tr>
</table>
<em>Automatticians: You can use our internal self-serve MC tool to give yourself access to those builds if needed.</em>
</details>

author_association: CONTRIBUTOR
user: login: sonarqubecloud[bot]
created_at: 2025-05-09T01:39:07Z
body: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=wordpress-mobile_WordPress-iOS&pullRequest=24518) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=wordpress-mobile_WordPress-iOS&pullRequest=24518&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=wordpress-mobile_WordPress-iOS&pullRequest=24518&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=wordpress-mobile_WordPress-iOS&pullRequest=24518&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=wordpress-mobile_WordPress-iOS&pullRequest=24518&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=wordpress-mobile_WordPress-iOS&pullRequest=24518&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=wordpress-mobile_WordPress-iOS&pullRequest=24518)


author_association: NONE