Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[match][sigh] add support for Apple Silicon Macs in iOS/iPadOS provisioning profiles #20676

Merged
merged 7 commits into from Nov 12, 2022
Merged

[match][sigh] add support for Apple Silicon Macs in iOS/iPadOS provisioning profiles #20676

merged 7 commits into from Nov 12, 2022

Conversation

PinkidG
Copy link
Contributor

@PinkidG PinkidG commented Sep 20, 2022

Checklist

  • I've run bundle exec rspec from the root directory to see all new and existing tests pass
  • I've followed the fastlane code style and run bundle exec rubocop -a to ensure the code style is valid
  • I see several green ci/circleci builds in the "All checks have passed" section of my PR (connect CircleCI to GitHub if not)
  • I've read the Contribution Guidelines
  • I've updated the documentation if necessary.

Motivation and Context

Resolves #18581

Macs with Apple Silicon (AS) are capable of running native iOS/iPadOS apps. During development this only works if the Mac is added to the provisioning profile (development or ad-hoc).

Description

This PR introduces a new device-class (APPLE_SILICON_MAC) that is used for iOS/iPadOS provisioning profiles to include AS Mac hardware. Including these devices is required to natively run apps on AS during development or using an ad-hoc signing.

To include AS Macs, a new parameter has been added to match (and sigh): include_mac_in_profiles. Default is false. If enabled the provisioning profile device count and newly generated profiles will include registered AS Macs.

If no AS Mac is registered in the Developer Portal, this setting won't have any effect. If run again without the include_mac_in_profiles flag, it will regenerate the provisioning profile without the AS Macs. (So it makes sense to include this setting in the Matchfile to keep it consistent)

Testing Steps

  1. Make sure to have at least one Apple Silicon Mac registered in the Developer Portal.
  2. Create a provisioning profile with fastlane match development --include_mac_in_profiles
  3. Check in Developer Portal that the newly created profile contains the AS Mac
  4. Rerunning fastlane match without include_mac_in_profiles set, will regenerate the profile without the AS Macs.

@google-cla
Copy link

google-cla bot commented Sep 20, 2022

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

Copy link
Member

@rogerluan rogerluan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this PR @PinkidG ! 💪

Could you update the related specs? e.g. sigh/spec/runner_spec.rb and match/spec/runner_spec.rb (not sure if there are others) 🙏

match/lib/match/options.rb Outdated Show resolved Hide resolved
@rogerluan rogerluan changed the title [match] Add support for Apple Silicon Macs in iOS/iPadOS provisioning profiles [match] add support for Apple Silicon Macs in iOS/iPadOS provisioning profiles Sep 20, 2022
Philipp Pinkernelle and others added 2 commits September 20, 2022 13:58
Update match ENV name

Co-authored-by: Roger Oba <rogerluan.oba@gmail.com>
@PinkidG
Copy link
Contributor Author

PinkidG commented Sep 20, 2022

@rogerluan Thanks for reviewing it! I added changes to the related specs, though I'm not sure if the sigh/spec/runner_spec.rb is correct.

Comment on lines 154 to 169
it "devices for development with apple silicon" do
options = { development: true, include_mac_in_profiles: true }
Sigh.config = FastlaneCore::Configuration.create(Sigh::Options.available_options, options)

ios_device = "ios_device"
allow(ios_device).to receive(:id).and_return(1)
allow(ios_device).to receive(:device_class).and_return(Spaceship::ConnectAPI::Device::DeviceClass::IPHONE)
as_device = "as_device"
allow(as_device).to receive(:id).and_return(2)
allow(as_device).to receive(:device_class).and_return(Spaceship::ConnectAPI::Device::DeviceClass::APPLE_SILICON_MAC)

expect(Spaceship::ConnectAPI::Device).to receive(:all).and_return([ios_device, as_device])

devices = fake_runner.devices_to_use
expect(devices.size).to eq(2)
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works but I kinda have the feeling you're allowing too many statements here 😬 not sure if this really attests the functionality you implemented, what do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ping @PinkidG , WDYT? :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @rogerluan Thanks for the feedback, I'm sorry I didn't get back to it. I'm not really a ruby expert tbh. 😅

I'll try to improve it 🙂

@juliengdt
Copy link

Ahoy, bump for this PR. it's a must have feature !

thanks !!

Copy link
Member

@rogerluan rogerluan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this, @PinkidG ! 🤗

@joshdholtz joshdholtz changed the title [match] add support for Apple Silicon Macs in iOS/iPadOS provisioning profiles [match][sigh] add support for Apple Silicon Macs in iOS/iPadOS provisioning profiles Nov 12, 2022
Copy link
Member

@joshdholtz joshdholtz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great! I added one commit with a comment about the device class not being officially available in ASC API yet but other than that this is 🔥

@joshdholtz joshdholtz merged commit 56db40b into fastlane:master Nov 12, 2022
@zakkhoyt
Copy link

zakkhoyt commented Nov 16, 2022

Hi @PinkidG. Thanks for putting this PR together.

Question for you (or anyone else knowledgeable).

I couldn't get my AS macs registered by using this PR, and feel like I'm missing some information or misunderstanding a key part.

From the PR Testing Steps:

  1. Make sure to have at least one Apple Silicon Mac registered in the Developer Portal.

Looking through the sigh/match code, it appears to me that in order for this PR to work that each registered device.device_class must be "APPLE_SILICON_MAC". Is this correct?

  • If so, how do you accomplish this?
  • If not, what am I misunderstanding?

When adding a new device with the Apple developer portal, you can choose the platform from a drop list, but I don't think this is even the correct property.


The fastlane tools register_devices and register_device both don't allow you to specify device_class either (only platform).

Do I need to use Apple's Rest API?

Am I off track here? Overlooking something?

Thx for reading.

@PinkidG
Copy link
Contributor Author

PinkidG commented Nov 16, 2022

Hi @zakkhoyt 🙂

I can't speak for the register_device action from fastlane. There might still need to be some adjustments. However, if you go through the developer portal and register an AS Mac, you'd choose macOS as platform.

Apple introduced a small change with AS Mac devices. They have two IDs that you can register: the Hardware UUID and the Provisioning UDID. You can find both in the System Profiler. On an Intel machine they're identical. For an AS Mac they're different and depending on which one you register, they're treated differently.

If you register the Hardware UUID you can create provisioning profiles for a macOS application. If you chose to register the Provisioning UDID the Mac will appear as an option to be included in your iOS/iPadOS profiles.

Of course you can register both IDs, even though they are both for the platform macOS, they are not mutual exclusive.
So in your case I'd verify, that you used the Provisioning UDID for registering your AS Macs. IMO, that should also work with the register_device action. At least it's easy to try out 😄.

Hope that helps a bit!

@fastlane-bot
Copy link

Congratulations! 🎉 This was released as part of fastlane 2.211.0 🚀

@ArtFeel
Copy link

ArtFeel commented Mar 31, 2023

He @PinkidG, thanks for PR, but I have same problem as described by @zakkhoyt

I found that if you register your device as a macOS (platform). Then it will not be added to the generated provision profile. It doesn't matter which UUID or UDID you specify. UDID-based AS mac is visible as option in iOS profile, but it remains unchecked.

But if you register your mac Provisioning UDID as iOS, tvOS, watchOS (platform).
Then it will be added to generated profile and be visible in devices list as iPod 🤯 :

image

In generated profile:

image

Fastlane params:

+-------------------------------------+----------------------------------+
|                        Summary for sigh 2.211.0                        |
+-------------------------------------+----------------------------------+
| app_identifier                      | my.id.app                        |
| username                            | user@apple.com                   |
| force                               | true                             |
| cert_id                             | **********                       |
| provisioning_name                   | match Development my.id.app      |
| ignore_profiles_with_different_name | true                             |
| api_key                             | ********                         |
| team_name                           | ****** ***                       |
| fail_on_name_taken                  | false                            |
| include_all_certificates            | false                            |
| include_mac_in_profiles             | true                             |
| platform                            | ios                              |
| development                         | true                             |
| adhoc                               | false                            |
| developer_id                        | false                            |
| skip_install                        | false                            |
| skip_fetch_profiles                 | false                            |
| skip_certificate_verification       | false                            |
| readonly                            | false                            |
+-------------------------------------+----------------------------------+

@jaysoffian
Copy link
Contributor

jaysoffian commented May 23, 2023

@ArtFeel, @PinkidG, @zakkhoyt, there's apparently a bug, or at least inconsistency in the App Store Connect API as of this comment.

When I query the App Store Connect API while using an API key, it returns MAC as the deviceClass for all Macs, whether Intel or Apple Silicon. If I query the API while using a username/password to access it, it returns the exact same devices with a deviceClass of either INTEL_MAC or APPLE_SILICON_MAC.

I've worked around this in a custom action I use for adding devices to profiles by checking the length of the UDID:

        Spaceship::ConnectAPI::Device.all.select(&:enabled?).each do |d|
          c = d.device_class
          case
          when ios_device_classes.include?(c) then ios_devices.push(d)
          when tvos_device_classes.include?(c) then tvos_devices.push(d)
          when mac_arm_device_classes.include?(c) then mac_arm_devices.push(d)
          when mac_intel_device_classes.include?(c) then mac_intel_devices.push(d)
          # When accessing the App Store Connect API using an API key, Mac devices are
          # returning using a generic "MAC" device class instead of a more specific class of
          # "APPLE_SILICON_MAC" or "INTEL_MAC" as is the case when accessing the API using a
          # username/password. As a work-around, we use the length of the UDID to discern
          # Intel Macs (UDID of length 36) from Apple Silicon Macs (UDID of length 25).
          when mac_generic_device_classes.include?(c) then
            case d.udid.length
            when 25 then mac_arm_devices.push(d)
            when 36 then mac_intel_devices.push(d)
            else UI.message("Unexpected UDID length: #{d.udid}")
            end
          else UI.message("Unexpected device class: #{c} (#{d.udid})")
          end
        end

Where:

      def self.ios_device_classes
        [
          Spaceship::ConnectAPI::Device::DeviceClass::APPLE_WATCH,
          Spaceship::ConnectAPI::Device::DeviceClass::IPAD,
          Spaceship::ConnectAPI::Device::DeviceClass::IPHONE,
          Spaceship::ConnectAPI::Device::DeviceClass::IPOD
        ]
      end

      def self.tvos_device_classes
        [Spaceship::ConnectAPI::Device::DeviceClass::APPLE_TV]
      end

      def self.mac_arm_device_classes
        [Spaceship::ConnectAPI::Device::DeviceClass::APPLE_SILICON_MAC]
      end

      def self.mac_intel_device_classes
        ["INTEL_MAC"]
      end

      def self.mac_generic_device_classes
        [Spaceship::ConnectAPI::Device::DeviceClass::MAC]
      end

Try using a username/password with Fastlane vs API key and see if that makes a difference in behavior for you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

MATCH does not comply with Apple (developer) profiles for iOS Apps running on Apple Silicon (M1)
8 participants