Difference between Xcode and git for resolving swift packages

For CI pipelines where you cannot sign into GitHub or other repository hosts this is the solution I found that bypasses the restrictions/bugs of Xcode around private Swift packages.

Use https urls for the private dependencies because the ssh config is currently ignored by xcodebuild even though the documentation says otherwise.

Once you can build locally with https go to your repository host and create a personal access token (PAT). For GitHub instructions are found here.

With your CI system add this PAT as a secret environment variable. In the script below it is referred to as GITHUB_PAT.

Then in your CI pipeline before you run xcodebuild make sure you run an appropriately modified version of this bash script:

for FILE in $(grep -Ril "https://github.com/[org_name]" .); do
    sed -i '' "s/https:\/\/github.com\/[org_name]/https:\/\/${GITHUB_PAT}@github.com\/[org_name]/g" ${FILE}
done

This script will find all https references and inject the PAT into it so it can be used without a password.

Don't forget:

  • Replace [org_name] with your organization name.
  • Replace ${GITHUB_PAT} with the name of your CI Secret if you named it differently.
  • Configure the grep command to ignore any paths you don't want modified by the script.

This seems to be a bug in Xcode 11 with SSH. Switching to HTTPS for resolving Swift Packages fixes the issue:

So from this:

E29801192303068A00018344 /* XCRemoteSwiftPackageReference "ProjectDependency" */ = {
        isa = XCRemoteSwiftPackageReference;
        repositoryURL = "[email protected]:company-uk/ProjectDependency.git";
        requirement = {
                branch = "debug";
                kind = branch;
        };
};

to:

E29801192303068A00018344 /* XCRemoteSwiftPackageReference "ProjectDependency" */ = {
        isa = XCRemoteSwiftPackageReference;
        repositoryURL = "https://github.com/company-uk/ProjectDependency.git";
        requirement = {
                branch = "debug";
                kind = branch;
        };
};

Also, now that Xcode 12 is out, you can use that, where it's fixed.