Automatically add new devices to the Apple Developer Portal (GitHub Actions & Fastlane)

retyui

Davyd NRB

Posted on December 24, 2022

Automatically add new devices to the Apple Developer Portal (GitHub Actions & Fastlane)

It's no secret that in order to install Beta/Staging builds on your real iPhone device, you must first register it. You can perform it manually, but you'll need special admin privileges. Automatization is a different strategy to remove a human factor.

The approach must be easy and practical.

  1. Your repository contains a file named devices.txt that lists the allowed "UDIDs."
  2. After the addition of a fresh device to that list, the developer will submit a PR for code review.
  3. A CI/CD job that will run after the PR has been approved and merged to the main branch
  4. That's it. Install the app after being rebuilt with a new provisioning profile.

Now let's review implementation. I'll use GitHub Actions & Fastlane as an example.

First, we require a file called "devices.txt"

the file format is displayed below (or you can view an Apple Sample):

<UDID>tabulation<Name>tabulation<Type: ios or mac>

Example:

Device ID   Device Name Device Platform
a02fc03df7e12c5fb1ec247e8a14e2c3e4b7d68d    My iPhoneX  ios
00006000-000C551C02D2801E   My MacBook  mac
00008120-000C3C262478C09E   My iPhone14 ios
Enter fullscreen mode Exit fullscreen mode

⚠️ Warn: dev.to transforms ^^^ tabulation to spaces (be careful when copy an example above)


Now let's create a new lane in your Fastfile

Our new lane will make use of the actions match and register_devices.

platform :ios do
  desc 'Registers new devices to the Apple Dev Portal and update provisioning profiles'
  lane :register_new_device_id do
    ensure_env_vars(
      env_vars: [
        # a secret variable Git repo encryption password
        'MATCH_PASSWORD',
        # a secret variable used to clone repo of certs 
        # more: https://docs.fastlane.tools/actions/match/
        'MATCH_GIT_BASIC_AUTHORIZATION',
        # your App Store Connect API Key information
        # used by `register_devices` action to authenticate to App Store Connect
        # more: https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-hash-option
        'APP_STORE_CONNECT_API_KEY_JSON',
      ]
    )

    apiFile = Tempfile.new('api_key')
    apiFile.write(ENV['APP_STORE_CONNECT_API_KEY_JSON'])
    apiFile.close

    # will register iOS/Mac devices with the Developer Portal so that you can include them in your provisioning profiles
    register_devices(
      api_key_path: apiFile.path,
      devices_file: "./devices.txt"
    )

    # Update provisioning profiles after `register_devices`
    match(
      type: "adhoc",
      readonly: false,
      force_for_new_devices: true
    )

    match(
      type: "appstore",
      readonly: false,
      force_for_new_devices: true
    )
  end
end
Enter fullscreen mode Exit fullscreen mode

Next we need to create a new GitHub Actions workflow

Every time a devices.txt file changes in master, the .github/workflows/register_device.yml workflow will execute a job.

name: Mobile Automation

on:
  push:
    branches:
      - master
    paths:
      - '**/devices.txt' 
    # When PR that changing a `devices.txt` file will be merged, this workflow will be triggered

    steps:
      - uses: actions/checkout@v3 # checks-out your repository

      - name: Install Ruby 2.x # Required for Fastlane
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: '2.7.6' # set your version
          bundler-cache: true   # enable caching for bundler

      - name: Install Fastlane
        run: bundle install --jobs 4 --retry 3

      - name: Registers a new device to the Apple Dev Portal
        run: bundle exec fastlane ios register_new_device_id
        env:
          MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
          MATCH_GIT_BASIC_AUTHORIZATION: ${{ secrets.MATCH_GIT_BASIC_AUTHORIZATION }}
          APP_STORE_CONNECT_API_KEY_JSON: ${{ secrets.APP_STORE_CONNECT_API_KEY_JSON }}
Enter fullscreen mode Exit fullscreen mode

That's enough. I this example I omitted the 'match' integration, but there are several guides online that explain how to implement it.

If you have any questions, please feel free to ask them in the comments section.

MurAmur (c)

💖 💪 🙅 🚩
retyui
Davyd NRB

Posted on December 24, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related