Automating Git Repo Updates for SPM Binary Package

I'm researching how to set up automated binary SPM deployments to our internal services. Basically I upload the new xcframework to our storage backend, and then I update the Git repo defining our SPM Binary Package with the new URL.

But updating with the Git repo with the new URL via automation seems like the tricky part. I could have the automation find and replace the section of the Package.swift file referencing the URL. But I've always found find and replace kind of brittle. I was investigating having Package.swift go look for a text file in the same repo that contains the URL for the binary xcframework. But I can't seem to find a reliable way to get to the root of the SPM repository on the client machine to find a text file containing the xcframework URL.

Is there a canonical or community standard way to handle situations like this? I looked through the forums and I didn't see anything. Wanted to see if anyone else had worked with automated deployments of binary packages before I started digging deeper.

1 Like

You could have the url defined as let package1Url = "https://example.com/xcframework1.zip" and then your search and replace has to only look for the start of the line. So if you want to add multiple urls or change up other parts of the package definition, you can easily do that.

Modified version of the example from here: Distributing Binary Frameworks as Swift Packages | Apple Developer Documentation

// swift-tools-version:5.3
import PackageDescription

// vvv Automatically updated, don't modify
let package1url = "https://url/to/some/remote/xcframework.zip"
// ^^^ Automatically updated, don't modify

let package = Package(
    name: "MyLibrary",
    platforms: [
        .macOS(.v10_14), .iOS(.v13), .tvOS(.v13)
    ],
    products: [
        // Products define the executables and libraries a package produces, and make them visible to other packages.
        .library(
            name: "MyLibrary",
            targets: ["MyLibrary", "SomeRemoteBinaryPackage", "SomeLocalBinaryPackage"])
    ],
    dependencies: [
        // Dependencies declare other packages that this package depends on.
    ],
    targets: [
        // Targets are the basic building blocks of a package. A target can define a module or a test suite.
        // Targets can depend on other targets in this package, and on products in packages this package depends on.
        .target(
            name: "MyLibrary"
        ),
        .binaryTarget(
            name: "SomeRemoteBinaryPackage",
            url: package1url,
            checksum: "The checksum of the ZIP archive that contains the XCFramework."
        ),
        .binaryTarget(
            name: "SomeLocalBinaryPackage",
            path: "path/to/some.xcframework"
        )
        .testTarget(
            name: "MyLibraryTests",
            dependencies: ["MyLibrary"]),
    ]
)