SPM, Github, internal dependencies & SSH auth

Ever tried using Swift Package Manager with dependencies hosted on Github while using SSH? And resolving subdependencies when adding a SPM package through Xcode? Still having nightmare about it? Dry your tears and cry no more: you've come to the right place.

SPM, Github, internal dependencies & SSH auth
Photo by Bradford Nicolas / Unsplash

Some companies and open source libraries reference Swift Package Manager dependencies using the https:// endpoint, such as https://github.com/org/repo.git. Some companies even use the https URLs for their own internal dependencies.

This can lead to the following issue when you are used to authenticate with Github using an SSH key

Fetching from https://github.com/org/repo.git
skipping cache due to an error: Failed to clone repository https://github.com/org/repo.git:
    Cloning into bare repository '/Users/user/Library/Caches/org.swift.swiftpm/repositories/repo-d43c1afe'...
    remote: Repository not found.
    fatal: repository 'https://github.com/org/repo.git/' not found

Or this issue, when adding SPM dependencies using Xcode

Which won't go away despite selecting a valid account from the drop down and inputting, again and again, a valid github personal access token. Why? Because somehow Xcode can't deal with the mixing up of both https URLs and ssh keys.

Which is tiring.

How do we solve that?

Tell git to use SSH instead of https

Although it won't be enough for Xcode (because Xcode), this will help when resolving dependencies from the command line. It can be done using insteadOf.

Either by adding the following to our ~/.gitconfig file (thanks Wazza):

[url "ssh://[email protected]/"]
  insteadOf = https://github.com/

Or by running the following command (thanks BillinghamJ):

git config --global url.ssh://[email protected]/.insteadOf https://github.com/

Tell Xcode to use the same git as everyone else

Why isn't enough for Xcode? Because Xcode is Xcode. Xcode is special, and Xcode doesn't care for our punny preferences and constraints. Xcode knows the One And Only True Way. The Best Way. Giant XMLs, lots of cached transient state all over the place and, above all else, more assumptions—held more firmly—than an army of conspiracy theorists, armchair epidemiologists-turned-generals, engaging in a tweet war over the events of the last four years.

Luckily, despite all that, our beloved benevolent leaders the engineers behind Xcode have a long tradition of discreetly exposing settings and preferences, allowing us to tell Xcode to use your actual system git. Allowing to tell Xcode to use the same git as everyone with a single command, courtesy of ukostas:

defaults write com.apple.dt.Xcode IDEPackageSupportUseBuiltinSCM YES

Epilogue

There you go. SPM and SSH, finally working well together. The best of both wo... Ah, no. I can't do this. Who am I kidding? The only good dependency management experience I've ever had in the last few years has been with bazel. Thanks a bunch, Corentin! You ruined SPM for me.