Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save tshego3/a51f248824141b1c11de79c73e05ae0f to your computer and use it in GitHub Desktop.

Select an option

Save tshego3/a51f248824141b1c11de79c73e05ae0f to your computer and use it in GitHub Desktop.
Setting up a Azure DevOps self-hosted agent on macOS

The Definitive macOS Azure DevOps Self-Hosted Agent Guide

Setting up a self-hosted agent on macOS is a great way to gain control over your build environment, especially for iOS or macOS-specific tasks (like Xcode builds) that require specific versions or tools.

As of 2026, the v3.x agent is the standard, supporting both Intel (x64) and Apple Silicon (ARM64) Macs.

1. Prerequisites

Before touching your Mac, ensure you have the following:

  • A Mac running macOS 11.0 (Big Sur) or later.
  • Azure DevOps Permissions: You must be an Agent Pool Administrator in your organization.
  • A Personal Access Token (PAT):
  1. In Azure DevOps, go to User Settings (top right) > Personal access tokens.
  2. Click + New Token.
  3. Click Show all scopes at the bottom.
  4. Select the scope: Agent Pools (Read & Manage).
  5. Copy the token immediately - you won't see it again.

2. Download the Agent

  1. Log in to your Azure DevOps organization (https://dev.azure.com/{your-org}).
  2. Go to Organization Settings (bottom left) > Agent pools.
  3. Select the Default pool (or create a new one).
  4. Click the Agents tab and then click New agent.
  5. Select macOS and choose your architecture:
  • x64: For Intel Macs.
  • ARM64: For Apple Silicon (M1, M2, M3, M4) Macs.
  1. Click Download.

3. Installation Steps

Open your Terminal on the Mac and run these commands:

Clear the extended attribute on the tar file

xattr -c ~/Downloads/vsts-agent-osx-x64-4.266.2.tar.gz

Create the directory

mkdir my-agent && cd my-agent

Unpack the agent

Replace the filename below with the one you actually downloaded:

tar zxvf ~/Downloads/vsts-agent-osx-x64-4.266.2.tar.gz

Configure the agent

Run the config script. It will ask you for details interactively:

./config.sh

What to enter when prompted:

  • Server URL: https://dev.azure.com/{your-organization}
  • Authentication type: Press Enter (defaults to PAT).
  • Personal access token: Paste the PAT you created earlier.
  • Agent pool: Press Enter (defaults to "Default").
  • Agent name: Give it a friendly name (e.g., Mac-Mini-01).
  • Work folder: Press Enter (defaults to _work).

4. Run the Agent

You can run the agent in two ways:

Option A: Interactive Mode (For Testing)

This runs the agent directly in your terminal. If you close the terminal, the agent stops.

./run.sh

Option B: As a Service (Recommended)

This ensures the agent starts automatically when the Mac boots and runs in the background.

# Install the service
./svc.sh install
# Start the service
./svc.sh start

5. Tips for 2026

  • Stay Updated: Agents usually auto-update, but you can manually trigger an update by right-clicking the pool in Azure DevOps and selecting Update all agents.
  • Xcode Versions: If you are building iOS apps, ensure you have the correct version of Xcode installed on the Mac. The agent will automatically detect it as a "Capability."
  • Security: If you get a "Developer cannot be verified" popup on macOS, run: xattr -rd com.apple.quarantine ~/my-agent

8. Troubleshooting Demands (MSBuild / JDK)

When running MAUI or Android pipelines, you may encounter an error: ##[error]No agent found in pool Default satisfies both of the following demands: MSBuild, JDK

On macOS (especially Apple Silicon), the agent doesn't always automatically register these capabilities even if the tools are installed.

The Problem

  • MSBuild Demand: Modern .NET (MAUI) uses the dotnet CLI. The MSBuild demand is often a legacy check that macOS agents don't "claim" by default.
  • JDK Demand: Tasks like AndroidSigning@3 automatically add a hidden demand for JDK.

The Solution: Manually Add Capabilities

Satisfy these demands in the Azure DevOps portal without changing your code:

  1. In Azure DevOps, go to Project Settings > Agent pools.
  2. Select your pool (e.g., Default) and click the Agents tab.
  3. Select your agent (e.g., Mac-M3-Build-01) and go to the Capabilities tab.
  4. Click Add capability and add the following:
Key Value (Example)
MSBuild /usr/local/share/dotnet/dotnet
JDK /Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home

Note: You can usually just use True as the value if you aren't using the capability to define a path.


9. Summary Table of Commands

Action Command
Check Status ./svc.sh status
Stop Agent ./svc.sh stop
Start Agent ./svc.sh start
Remove Agent ./svc.sh uninstall then ./config.sh remove

7. How to Use the Agent

In your azure-pipelines.yml file, ensure your pool block matches the name of the pool where you registered the Mac:

pool:
  name: 'Default'
  demands:
  - Agent.Name -equals Mac-M3-Build-01 # Targets your specific machine
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment