Automatically add new devices to the Apple Developer Portal (GitHub Actions & Fastlane)
Tags: cicd, ios, fastlane, github
Published: 2022-12-24 21:00:19

---
title: Automatically add new devices to the Apple Developer Portal (GitHub Actions & Fastlane)
published: true
description: 
tags: cicd, ios, fastlane, github
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sfaifihl1wddosgk8mbn.png
# Use a ratio of 1 for best results.
# published_at: 2022-12-24 19:33 +0000
---


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](http://devimages.apple.com/downloads/devices/Multiple-Upload-Samples.zip)):

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


Example:

```csv
Device ID	Device Name	Device Platform
a02fc03df7e12c5fb1ec247e8a14e2c3e4b7d68d	My iPhoneX	ios
00006000-000C551C02D2801E	My MacBook	mac
00008120-000C3C262478C09E	My iPhone14	ios
```
> ⚠️ 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`](https://docs.fastlane.tools/actions/match/) and [`register_devices`](https://docs.fastlane.tools/actions/register_devices/).

```ruby
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
```

---


### 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.


```yml
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 }}
```

---

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)