Command line Update of Provisioning Profiles

32,036

Solution 1

Here's my bash script for it, where the first argument to the script ($1) is the location of the new profiles.

rm -Rf ~/Library/MobileDevice/Provisioning\ Profiles/*
cp "$1"/*.* ~/Library/MobileDevice/Provisioning\ Profiles/

Basically, anything in that ~/Library/MobileDevice/Provisioning Profiles/ folder can be used to build with (and will show up in Xcode).

If you're looking to stand up a CI system, I recently gave a talk on using Hudson for it, and put up some slides and notes over here. My email is on my site if you have any questions about it.

Solution 2

Update: Cupertino will no longer work on latest iTunes. Look into using sigh instead


Sounds like this command line interface will help out big time:

https://github.com/nomad/cupertino

which allows you to download all distribution profiles like so (thanks @tdubik):

ios profiles:download:all --type distribution

Another approach would be to use an Enterprise development license ($300/year) that lets you build for devices without provisioning! So you can build your app, and send it to a device without ever needing to go to the Apple Dev center or register any new devices.

Note that this wouldn't allow you to distribute your app to the appstore, but if you're a development house that builds tons of apps for clients, it may ease your "build and send to clients" process quite a piece! I'm not sure if this would be in Apple's legitimate use policies or not, so please check that out before considering that option. But it might be something to consider for prototypes, etc, and when they actually want to ship it, you get them to get their own developer program license.

Solution 3

Try using apple_dev_center.rb from https://github.com/lacostej/apple-dev

It parses the info from the apple developer web site and download the profiles for you to copy them to the proper location automatically.

Solution 4

Sigh can manage provisioning profiles for you. However, it doesn't support installing profiles that you've fetched yourself already. However, I still found it valuable to look at their source for how they actually install a profile once they've downloaded it.

Thankfully, it's very similar to James J's answer:

def self.install_profile(profile)
  UI.message "Installing provisioning profile..."
  profile_path = File.expand_path("~") + "/Library/MobileDevice/Provisioning Profiles/"
  uuid = ENV["SIGH_UUID"] || ENV["SIGH_UDID"]
  profile_filename = uuid + ".mobileprovision"
  destination = profile_path + profile_filename

  # If the directory doesn't exist, make it first
  unless File.directory?(profile_path)
    FileUtils.mkdir_p(profile_path)
  end

  # copy to Xcode provisioning profile directory
  FileUtils.copy profile, destination

  if File.exist? destination
    UI.success "Profile installed at \"#{destination}\""
  else
    UI.user_error!("Failed installation of provisioning profile at location: #{destination}")
  end
end

I have a script to perform this local installation for me:

#!/bin/bash -euo pipefail

BASH_SOURCE_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

cd "$BASH_SOURCE_DIR"

# by default bash passes the glob characters if nothing matched the glob
# disable that
# http://stackoverflow.com/a/18887210/9636
shopt -s nullglob
# this creates a proper bash array, which we need since our profiles
# have funny characters in them
MOBILE_PROVISIONS=(*.mobileprovision)
# re-enable default nullglob behavior
shopt -u nullglob

# On a brand new machine that has never run any app on a development device
# the ~/Library/MobileDevice/"Provisioning Profiles" directory doesn't exist
mkdir -p ~/Library/MobileDevice/"Provisioning Profiles"

for mobileprovision in "${MOBILE_PROVISIONS[@]}"
do
  uuid=$( ./uuid-from-mobileprovision.bash "${mobileprovision}" )
  cp "${mobileprovision}" ~/Library/MobileDevice/"Provisioning Profiles"/"${uuid}".mobileprovision
done

which depends on another uuid-from-mobileprovision.bash script:

#!/bin/bash -euo pipefail

if [ ! -f "${1}" ]
then
  echo "Usage: $0 <path/to/mobileprovision/file>" 1>&2
  exit 1
fi

UUID=$( grep --text --after-context=1 UUID "${1}" | grep --ignore-case --only-matching "[-A-Z0-9]\{36\}" )
if [ -z "${UUID}" ]
then
  echo "Invalid mobileprovision file: ${1}" 1>&2
  exit 2
else
  echo "${UUID}"
fi

Solution 5

I have been trying to make this work for sometime. Finally made it!!

Can use fastlane sigh to download and install only the provisional profile you need.

fastlane sigh renew --adhoc -n "provisional_profile_name"
--app_identifier "your_app_identifier" -u "apple_login _username" --ignore_profiles_with_different_name

Note : This command needed any provisional profile of the app already installed in the system. It thrown error for me otherwise.

provisional_profile_name = Just the name of the profile name, doesn't need extension.

Share:
32,036
Blitz
Author by

Blitz

Updated on July 29, 2022

Comments

  • Blitz
    Blitz almost 2 years

    I couldn't find anything on this (maybe I'm just using the wrong search terms..):
    We're trying to build a sensible continuous integration setting for our apps. To have a REALLY sensible implementation, the build server should be able to automatically refresh the used provisioning profiles from apple. Similar to what the X-Code organizer does, but automagically via command line.
    Any clue if that's possible at all?

  • Blitz
    Blitz over 13 years
    cool, thanks for the answer. But do you have any idea how to get $1? How do you get the profiles onto your build machine in the first place?
  • James J
    James J over 13 years
    My work is primarily contracting, and each client has their own iTunes Connect account, so I've delegated that back to them. Trained them on how to update provisioning profiles with new UDIDs, and I've shared a Dropbox.com folder with each of them where they keep their specific provisioning profiles. First step of my build process is updating the provisioning profiles with the client specific ones on Dropbox, so builds always use the latest. Uploading a new profile is also a build trigger, so they can add new devices and get a fresh build without my intervention.
  • Blitz
    Blitz over 13 years
    okay, that makes sense. How do you trigger a new build using a dropbox? Folderactions? Or is there a specific option to do this?
  • James J
    James J over 13 years
    I have a plugin installed in Hudson, forget the name, that checks if the contents of a folder have changed. This is configured on a project-by-project basis, each project in Hudson checks a project-specific folder in Dropbox for changes (i.e. a new provisioning profile).
  • ckhan
    ckhan about 12 years
    What's notable to me about this solution is that it illustrates you don't need to rename the file to <provid>.mobileprovision, which is what happens to it when you use XCode (I'm on 4.2) to import the file. That means the --embed argument to xcrun ... PackageApplication can be stable, which makes automation a lot easier.
  • theblackips
    theblackips about 11 years
    @James J, what about the project files themselves? Can those be updated automatically to use the new prov file? That is, I have 5 projects that all use the same DEV prov, currently I have to go into all 5 XCode projects and manually pick the correct provisioning file. I'd like to automate that as part of my build instead. Current thought, some awk/sed script to blast the right UDID into the proj file...
  • danieljimenez
    danieljimenez over 10 years
    Enterprise licenses aren't for App Store distribution, so you'd have to have another developer account with Apple to use this productively (assuming you plan to ship your apps to the App Store).
  • Sperr
    Sperr over 10 years
    Thanks for the github link! Best answer here. However, I wouldn't recommend using Enterprise for building apps for clients - Apple doesn't like that. Enterprise is "for internal deployment within the company only", and I believe the agreement says you must be in control of all the devices that are used with Enterprise.
  • Brad Parks
    Brad Parks over 10 years
    Yeah I wasn't sure if that was true or not.... I expected as much and figured someone more informed than I would know... thanks for the clarification!
  • Tomasz Dubik
    Tomasz Dubik almost 9 years
    with cupertino it's easy as ios profiles:download:all --distribution
  • Tom
    Tom almost 8 years
    @thadon xcodebuild takes a -exportProvisioningProfile "profile name" argument that I believe accomplishes what you want. My assumption is that "profile name" is matched against the list of files inside ~/Library/MobileDevice/Provisioning\ Profiles/.
  • Toland Hon
    Toland Hon almost 8 years
    Here's the link to sigh, a tool developed by Fastlane to manage provisioning profiles (create, download, renew, repair): github.com/fastlane/fastlane/tree/master/sigh#readme
  • AnneTheAgile
    AnneTheAgile over 6 years
    this appears to be how to do it; 1.PREREQ sudo gem install fastlane; xcode-select --install; 2.Call download_all ; $ fastlane sigh download_all -i certID -u "[email protected]"
  • Elliott B
    Elliott B over 5 years
    Can fastlane work with a free dev account? It keeps giving me an error that I don't have permission for user_details_data
  • Colin Cornaby
    Colin Cornaby about 3 years
    Old post but just adding in for posterity - Enterprise builds still have to be signed with provisioning profiles. Same process, different profiles. You're also not allowed to technically send these builds outside of your company, so this also can be a violation of your account terms.