Orchestrating macOS CI/CD: Self-Hosted Runner Configuration and the macOS 26 Transition

The landscape of continuous integration and continuous deployment (CI/CD) within the Apple ecosystem has undergone significant evolution, moving from simple script execution to sophisticated, automated workflows that handle containerization, package management, and complex matrix builds. GitHub Actions serves as the central nervous system for these operations, allowing developers to automate workflows ranging from welcoming new users in open-source projects to deploying web services and building applications in languages such as Node.js, Python, Java, Ruby, PHP, Go, Rust, and .NET. While GitHub provides hosted runners for Linux, macOS, Windows, ARM, GPU, and containerized environments, organizations often require the granularity and control offered by self-hosted solutions. This shift is particularly pronounced for macOS development, where hardware constraints, licensing, and specific tooling requirements necessitate a deeper understanding of both self-hosted configuration on devices like the Mac mini and the ongoing transitions in GitHub’s hosted runner images, such as the recent general availability of macOS 26.

Architecting Self-Hosted macOS Runners on Hardware

Self-hosted runners provide increased control and customization for CI/CD setups, bypassing the pay-as-you-go model of online runners. Setting up a self-hosted runner on a Mac mini requires a methodical approach to user management, software installation, and secure authentication. The process begins with strict prerequisites: a Scaleway account logged into the console (or equivalent cloud provider access), owner status or IAM permissions for the organization, a physical Mac mini, and administrator rights to the target GitHub repository. Additionally, a package manager, preferably Homebrew, must be installed to facilitate software dependency management.

The security and operational integrity of a self-hosted runner depend heavily on isolating the CI/CD processes from the host system’s primary user accounts. The recommended procedure involves creating a dedicated service account named gh-runner. This account must be added to the admin group to possess the necessary privileges for installing software and managing system configurations without compromising the host administrator's primary credentials. The creation of this user is executed through the Directory Service command-line utility (dscl), which configures the user's shell, unique identifier, group ID, and home directory.

```bash

Create the 'gh-runner' user account

sudo dscl . -create /Users/gh-runner
sudo dscl . -create /Users/gh-runner UserShell /bin/bash
sudo dscl . -create /Users/gh-runner RealName "GitHub runner"
sudo dscl . -create /Users/gh-runner UniqueID "1001"
sudo dscl . -create /Users/gh-runner PrimaryGroupID 20
sudo dscl . -create /Users/gh-runner NFSHomeDirectory /Users/gh-runner

Set the password of the user. Replace 'password' with the actual password you want to configure for the user.

sudo dscl . -passwd /Users/gh-runner password

Add 'gh-runner' to the 'admin' group

sudo dscl . -append /Groups/admin GroupMembership gh-runner
```

Once the user account is provisioned, the system must be prepared for the specific requirements of macOS development and GitHub Actions runtime. This involves ensuring that Git is available and, crucially, that Rosetta 2 is installed. Rosetta 2 is essential for self-hosted ARM64 Macs to execute x64 binaries, a common requirement in legacy CI/CD pipelines that have not yet fully migrated to native ARM architecture. The installation of Rosetta 2 can be triggered via the softwareupdate command if it is not already present.

```bash
su gh-runner
git --version

Assuming you have Homebrew installed. If not, follow the guides on https://brew.sh/ to install it.

brew install git

Install Rosetta 2 if not already installed

softwareupdate --install-rosetta
```

With the environment prepared, the connection to GitHub is established through the repository settings. Navigating to the repository’s Actions settings and selecting the Runners tab reveals the interface for adding new hardware. Selecting "New self-hosted runner" redirects the administrator to a configuration page where the runner image must be specified as macOS and the architecture selected as ARM64 (or x64, depending on the hardware). The platform then generates a series of shell commands that authenticate the machine, download the necessary runtime binaries, and finalize the runner setup. This process ties the physical hardware directly to the GitHub organization, enabling it to execute workflows defined in .github/workflows files.

The Evolution of Hosted macOS Runner Images

While self-hosted runners offer control, the majority of GitHub Actions users rely on GitHub-hosted runners. These runners are subject to periodic updates and migrations that significantly impact CI/CD stability. A critical recent development is the general availability of the macOS 26 runner image. Previously in public preview, the macOS 26 image now provides a fully supported environment for building and testing applications with the latest macOS and Xcode tooling.

The macOS 26 runner image is architecturally significant because it runs natively on Apple Silicon (arm64) while maintaining support for Intel (x64) architectures. This dual-support capability allows developers to target specific hardware profiles in their workflow files using distinct labels. The availability of these runners expands the matrix build capabilities, allowing teams to test across different hardware architectures simultaneously to ensure binary compatibility and performance optimization.

The available labels for macOS 26 runners are categorized by size and architecture:

  • macos-26: Standard macOS runner for arm64.
  • macos-26-intel: Standard macOS runner for x64.
  • macos-26-large: Large runner for x64.
  • macos-26-xlarge: Extra-large runner for arm64.

This granularity allows organizations to scale their resource allocation based on the computational demands of their tests. For example, resource-intensive compilation tasks may utilize the large or xlarge runners, while lightweight linting or documentation builds can utilize the standard runners.

Migration Strategies and Legacy Support

The transition to new macOS versions in hosted runners is not instantaneous and requires careful planning to avoid breaking existing workflows. Prior to the arrival of macOS 26, GitHub initiated the migration of the macos-latest label to macos-15. This change was rolled out over a period of several weeks, beginning on August 4th, 2025, with a planned completion by August 30th, 2025. The motivation for this shift was to align the default runner image with the most recent stable macOS release, ensuring that users benefit from the latest security patches and software tools by default.

macos-15 had been in preview mode since September 2024 for GitHub Actions and March 18th, 2025 for Azure DevOps, before becoming generally available on April 10th, 2025. However, the migration to macos-15 as the default for the macos-latest label affects a broad range of runner images, including Ubuntu 22.04, Ubuntu 24.04, macOS 13 (Intel and Arm64), macOS 14 (Intel and Arm64), macOS 15 (Intel and Arm64), Windows Server 2019, Windows Server 2022, and Windows Server 2025.

During the transition period, organizations may encounter issues with workflows that were optimized for older macOS versions or that rely on deprecated software packages. To mitigate these risks, GitHub provides specific mitigation strategies. If a workflow fails due to the new environment, the immediate fallback is to pin the runner to a specific version, such as macos-14, by explicitly specifying the macos-14 label in the workflow file. This ensures stability while the development team updates their toolchains and dependencies to support the newer environment.

Network Considerations for Hosted Runners

Understanding the network topology of GitHub-hosted runners is essential for organizations that enforce strict firewall rules or operate within isolated network environments. Windows and Ubuntu runners are hosted in Azure and consequently share the same IP address ranges as Azure datacenters. In contrast, macOS runners are hosted in GitHub’s own macOS cloud, resulting in a distinct set of IP address ranges.

Due to the dynamic nature of these cloud-based runners, the list of IP addresses is extensive and subject to weekly updates via the GitHub REST API. Specifically, the actions key in the response of the GET /meta endpoint provides the current list. Because of the volume and frequency of these changes, GitHub explicitly advises against using these IP ranges as allowlists for internal resources. Instead, organizations requiring static IP connectivity should utilize larger runners with static IP ranges or opt for self-hosted runners, which offer predictable network addresses and easier integration with internal corporate firewalls.

Furthermore, GitHub-hosted runners must establish connections to specific GitHub-owned endpoints to perform essential communication operations. In addition to these mandatory connections, runners may require access to external networks specified within the actions themselves. Administrators configuring firewalls must ensure that these communications are allowed. It is also critical to note that some domains are configured using CNAME records, and certain firewall implementations may require recursive rules to resolve all CNAME targets properly. Failure to account for these network nuances can result in silent failures or timeouts during workflow execution.

Conclusion

The administration of macOS CI/CD pipelines in GitHub Actions requires a dual strategy: mastering the configuration of self-hosted runners for maximum control and staying vigilant about the evolving landscape of hosted runner images. Self-hosted setups on hardware like the Mac mini offer a cost-effective and customizable alternative to pay-as-you-go models, provided that proper security measures, such as dedicated user accounts and Rosetta 2 installation, are implemented. Simultaneously, the transition to newer macOS images, such as macOS 26, introduces powerful new capabilities for native Apple Silicon testing but demands proactive migration planning to avoid disruptions. By understanding the network implications, utilizing specific runner labels, and leveraging mitigation strategies like pinning to older versions, development teams can maintain robust, scalable, and secure CI/CD workflows in the macOS ecosystem.

Sources

  1. Install GitHub Actions runner on Mac - Scaleway
  2. macOS 15 default migration - GitHub Actions Runner Images
  3. GitHub Actions features - GitHub
  4. macOS 26 generally available for GitHub Actions - GitHub Changelog
  5. GitHub-hosted runners documentation - GitHub Docs

Related Posts