Skip to content

[bug]: This package breaks Dependabot for Apple platforms #885

@FelixHerrmann

Description

@FelixHerrmann

Description

Scenario

You have a Swift package for iOS only with some dependencies including algoliasearch-client-swift.

let package = Package(
    name: "ExamplePackage",
    platforms: [
        .iOS(.v16),
    ],
    dependencies: [
        .package(url: "https://github.com/algolia/algoliasearch-client-swift", exact: "9.27.0"),
        .package(url: "https://github.com/getsentry/sentry-cocoa", exact: "8.53.2"),
    ]
)

If you open this package in Xcode the os directive will be macOS and the Linux specific dependencies will be excluded on manifest compilation:

#if os(Linux)
extraPackageDependencies.append(contentsOf: [
.package(url: "https://github.com/apple/swift-crypto.git", from: "3.2.0"),
.package(url: "https://github.com/apple/swift-log.git", from: "1.5.4"),
])
extraTargetDependencies.append(contentsOf: [
.product(name: "Crypto", package: "swift-crypto"),
.product(name: "Logging", package: "swift-log"),
])
#endif
)

Therefor the local (macOS) Package.resolved does not contain those dependencies.

When setting up Dependabot for the package repository the Package.resolved diff in the resulting PRs will not only contain the version change but also the Linux-specific dependencies (see the attached logs) because Dependabot runs on ubuntu-latest runners; it will not compile there, just use swift package show-dependencies --format json which includes manifest compilation.

Solutions

I think it is generally not recommended to use os directives in the package manifest and this is a good example why. There are 2 proper fixes I can think of right now:

1) Remove all os directives in the manifest

Instead of making the dependencies conditional on the compilation level, always add them and specify the condition on each target dependency:

dependencies: [
    .product(name: "Crypto", package: "swift-crypto", condition: .when(platforms: [.linux])),
    .product(name: "Logging", package: "swift-log", condition: .when(platforms: [.linux])),
]

This has the downside Apple platforms will also fetch those dependencies but is not a big deal IMO.

2) Create separate repositories for Apple and Linux

This solution is more flexible because you get platform-specific manifests but has the downside of cross-platform consuming packages, e.g. a Vapor backend service that gets developed on macOS but deployed on Linux (in this scenario the conditional dependency is also problematic BTW); it could be solved by adding both packages and adding them with condition but could be not obvious.


I currently maintain an Apple-only fork to solve the issue for us but hope this can be addressed.

Client

All

Version

9.27.0

Relevant log output

diff --git a/Package.resolved b/Package.resolved
index 75468d6a..0bdd9193 100644
--- a/Package.resolved
+++ b/Package.resolved
@@ -1,5 +1,5 @@
 {
-  "originHash" : "34f9005d46d2014727c22ce7b6c9522e9fe354c702311d6408ca66b0872bfc70",
+  "originHash" : "fc9f6186bdff1d0ba70b7f5b30c847ba6e07ad82e2eab4eb3c7b13232ed05f0b",
   "pins" : [
     {
       "identity" : "algoliasearch-client-swift",
@@ -168,8 +168,8 @@
       "kind" : "remoteSourceControl",
       "location" : "https://github.com/getsentry/sentry-cocoa",
       "state" : {
-        "revision" : "ca92efeb24b10052cd2a79e5205f42c5a16770ec",
-        "version" : "8.53.2"
+        "revision" : "3c2eee7773df58bdfb9e10e72d9a4be44253e0d9",
+        "version" : "8.55.0"
       }
     },
     {
@@ -208,6 +208,15 @@
         "version" : "1.5.0"
       }
     },
+    {
+      "identity" : "swift-asn1",
+      "kind" : "remoteSourceControl",
+      "location" : "https://github.com/apple/swift-asn1.git",
+      "state" : {
+        "revision" : "f70225981241859eb4aa1a18a75531d26637c8cc",
+        "version" : "1.4.0"
+      }
+    },
     {
       "identity" : "swift-collections",
       "kind" : "remoteSourceControl",
@@ -217,6 +226,15 @@
         "version" : "1.1.4"
       }
     },
+    {
+      "identity" : "swift-crypto",
+      "kind" : "remoteSourceControl",
+      "location" : "https://github.com/apple/swift-crypto.git",
+      "state" : {
+        "revision" : "334e682869394ee239a57dbe9262bff3cd9495bd",
+        "version" : "3.14.0"
+      }
+    },
     {
       "identity" : "swift-eventsource",
       "kind" : "remoteSourceControl",
@@ -235,6 +253,15 @@
         "version" : "1.4.0"
       }
     },
+    {
+      "identity" : "swift-log",
+      "kind" : "remoteSourceControl",
+      "location" : "https://github.com/apple/swift-log.git",
+      "state" : {
+        "revision" : "ce592ae52f982c847a4efc0dd881cc9eb32d29f2",
+        "version" : "1.6.4"
+      }
+    },
     {
       "identity" : "swift-numerics",
       "kind" : "remoteSourceControl",

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions