skip to Main Content

I have a project and:

  • the company I’m working with is self-hosting their git
  • the CI can communicate only with company’s network

That being said, if I want to install any dependency, I have to ask their dev ops to mirror the target repository and only then I can use it.

The problem arises when I want to implement Crashlytics which has a lot of dependencies. When I import the Firebase, it’s fetched from the mirrored repo correctly, but it’s dependencies are still being fetched from the original URLs (which makes perfect sense).

The question is – How do I tell Swift Package Manager to swap each URL with mirrors? I have all the dependencies mirrored. I only need to tell SPM to use it.

I have found this proposal which was implemented in Swift 5, but when I go to root of my project and run:

$ swift package config set-mirror --package-url <original URL> --mirror-url <mirror URL>

I get this error:

error: root manifest not found

Any ideas how to do this correctly? Thank you

EDIT:

As Florian correctly pointed out, the proposal works from the package’s repository, not my projects! So:

  1. I do clone mirrored repo in my project’s root
  2. I run set of commands to set mirror url for each dependency:
swift package config set-mirror 
    --original-url https://github.com/google/GoogleAppMeasurement.git 
    --mirror-url <company's url>/mirrors/githubcom-google-GoogleAppMeasurement
  1. I go back to projects root and run:
xcodebuild -resolvePackageDependencies -project MyProject.xcodeproj -scheme MyAppScheme

But it’s still fetching from original urls, not the mirrors!

2

Answers


  1. Having an Xcode project makes this task basically impossible (at the time of writing). Xcode’s integration with SPM works fine for most things, but is not (yet?) at par with what SPM can do in pure SPM packages.

    The problem is, that swift package config is always only local to the package and does not have any effect on projects / packages that depend on the package. And with Xcode currently having no counterpart to swift package config, it’s not possible to do this at the moment.

    What you could do, however, is to clone all your dependencies locally and then reference them as local packages from Xcode (simply dragging the package folder into the open Xcode project will do so). Xcode will be smart enough to take the dependencies from the local local checkout (or at least it was smart enough last time I tried this).

    Let’s hope for a future Xcode version with full SPM support!

    Login or Signup to reply.
  2. SPM mirroring only works for packages, not applications.
    I faced withthe requirement to use on the CI the packages from an internal repository, while building on my workstations we are required to build from a public Github repo.

    The solution i went with is to "patch" the project.pbxproj file using a shell script.
    In the project.pbxproj the URL for the repository is set to be the public and is just a plain string.
    On the CI we use xcodebuild to build the application, and prior to the build / archive actions i run a shell script using sed to override the URL to the internal.

    #!/usr/bin/env bash
    
    set -e
    
    if [[ ! "${RUNNING_ON_CI}" ]]; then
        echo "Build is not running on the CI, skipping SPM URL update."
        exit 0
    fi
    
    PROJECT_FILE_PATH="${REPO_ROOT}/${PROJECT_NAME}.xcodeproj/project.pbxproj"
    sed -ie "s/[email protected]:Alamofire/Alamofire.git/[email protected]:Alamofire/Alamofire.git/g" "${PROJECT_FILE_PATH}"
    
    SED_BACKUP_FILE="${REPO_ROOT}/${PROJECT_NAME}.xcodeproj/project.pbxproje"
    if [ -f "${SED_BACKUP_FILE}" ]; then
        rm -rf "${SED_BACKUP_FILE}"
    fi
    

    It is not mirroring, since we always build from the internal repository on the CI, but it works.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search