Self-hosted macOS agents

In this article

In Microsoft Team Foundation Server (TFS) 2018 and previous versions,
run and release pipelines are called definitions,
runs are called builds,
service connections are called service endpoints,
stages are called environments,
and jobs are called phases.

To build and deploy Xcode apps or Xamarin.iOS projects, you'll need at least one macOS agent. This agent can also build and deploy Java and Android apps.

Otherwise, you've come to the right place to set up an agent on macOS. Continue to the next section.

Learn about agents

If you already know what an agent is and how it works, feel free to jump right in to the following sections. But if you'd like some more background about what they do and how they work, see Azure Pipelines agents.

Check prerequisites

Prepare permissions

If you're building from a Subversion repo, you must install the Subversion client on the machine.

You should run agent setup manually the first time.
After you get a feel for how agents work, or if you want to automate setting up many agents, consider using unattended config.

Decide which user you'll use

As a one-time step, you must register the agent. Someone with permission to
administer the agent queue
must complete these steps. The agent will not use this person's
credentials in everyday operation, but they're required to complete registration.
Learn more about how agents communicate.

Authenticate with a personal access token (PAT)

Sign in with the user account you plan to use in either your Azure DevOps organization (https://dev.azure.com/{your_organization})
or your Team Foundation Server web portal (https://{your-server}:8080/tfs/).

From your home page, open your profile. Go to your security details.

Create a personal access token.

For the scope select Agent Pools (read, manage) and make sure all the other boxes are cleared.
If it's a deployment group agent, for the scope select Deployment group (read, manage) and make sure all the other boxes are cleared.

Copy the token. You'll use this token when you configure the agent.

Authenticate as a Windows user (TFS 2015 and TFS 2017)

As an alternative, on TFS 2017, you can use either a domain user or a
local Windows user on each of your TFS application tiers.

On TFS 2015, for macOS and Linux only,
we recommend that you create a local Windows user on each of your TFS application tiers and dedicate that user for the purpose of deploying build agents.

Confirm the user has permission

Make sure the user account that you're going to use has permission to register the agent.

Is the user an Azure DevOps organization owner or TFS server administrator? Stop here, you have permission.

Otherwise:

Open a browser and navigate to the Agent pools tab for your Azure Pipelines organization or TFS server:

You can add a user to the deployment group administrator role in the Security tab on the Deployment Groups page in Azure Pipelines.

Note

If you see a message like this: Sorry, we couldn't add the identity. Please try a different identity., you probably followed the above steps for an organization owner or TFS server administrator. You don't need to do anything; you already have permission to administer the agent queue.

Download and configure the agent

Azure Pipelines

Log on to the machine using the account for which you've prepared permissions as explained above.

In your web browser, sign in to Azure Pipelines, and navigate to the Agent pools tab:

Choose Azure DevOps, Organization settings.

Choose Agent pools.

Select the Default pool, select the Agents tab, and choose New agent.

On the Get the agent dialog box, click macOS.

Click the Download button.

Follow the instructions on the page.

Unpack the agent into the directory of your choice. cd to that directory and run ./config.sh. Make sure that the path to the directory contains no spaces because tools and scripts don't always properly escape spaces.

::: moniker range=azure-devops-2019"

Azure DevOps Server 2019

Log on to the machine using the account for which you've prepared permissions as explained above.

In your web browser, sign in to Azure DevOps Server 2019, and navigate to the Agent pools tab:

Choose Azure DevOps, Organization settings.

Choose Agent pools.

Click Download agent.

On the Get agent dialog box, click macOS.

Click the Download button.

Follow the instructions on the page.

Unpack the agent into the directory of your choice. cd to that directory and run ./config.sh. Make sure that the path to the directory contains no spaces because tools and scripts don't always properly escape spaces.

::: moniker-end

TFS 2017 and TFS 2018

Log on to the machine using the account for which you've prepared permissions as explained above.

In your web browser, sign in to Azure Pipelines or TFS, and navigate to the Agent pools tab:

Unpack the agent into the directory of your choice. cd to that directory and run ./config.sh. Make sure that the path to the directory contains no spaces because tools and scripts don't always properly escape spaces.

TFS

When you configure your agent to connect to TFS, you've got the following options:

Alternate Connect to TFS using Basic authentication. After you select Alternate you'll be prompted for your credentials.

Integrated Not supported on macOS or Linux.

Negotiate (Default) Connect to TFS as a user other than the signed-in user via a Windows authentication scheme such as NTLM or Kerberos. After you select Negotiate you'll be prompted for credentials.

PAT Supported only on Azure Pipelines and TFS 2017 and newer. After you choose PAT, paste the PAT token you created into the command prompt window. Use a personal access token (PAT) if your TFS instance and the agent machine are not in a trusted domain. PAT authentication is handled by your TFS instance instead of the domain controller.

To use your agent, run a job using the agent's pool.
If you didn't choose a different pool, your agent will be in the Default pool.

Run as a launchd service

We provide the ./svc.sh script for you to run and manage your agent as a launchd LaunchAgent service. This script will be generated after you configure the agent. The service has access to the UI to run your UI tests.

Note

If you prefer other approaches, you can use whatever kind of service mechanism you prefer. See Service files.

Tokens

In the section below, these tokens are replaced:

{agent-name}

{tfs-name}

For example, you have configured an agent (see above) with the name our-osx-agent. In the following examples, {tfs-name} will be either:

Azure Pipelines: the name of your organization. For example if you connect to https://dev.azure.com/fabrikam, then the service name would be vsts.agent.fabrikam.our-osx-agent

TFS: the name of your on-premises TFS AT server. For example if you connect to http://our-server:8080/tfs, then the service name would be vsts.agent.our-server.our-osx-agent

Commands

Change to the agent directory

For example, if you installed in the myagent subfolder of your home directory:

cd ~/myagent$

Install

Command:

./svc.sh install

This command creates a launchd plist that points to ./runsvc.sh. This script sets up the environment (more details below) and starts the agent's host.

Update environment variables

When you configure the service, it takes a snapshot of some useful environment variables for your current logon user such as PATH, LANG, JAVA_HOME, ANT_HOME, and MYSQL_PATH. If you need to update the variables (for example, after installing some new software):

./env.sh
./svc.sh stop
./svc.sh start

The snapshot of the environment variables is stored in .env file under agent root directory, you can also change that file directly to apply environment variable changes.

Run instructions before the service starts

You can also run your own instructions and commands to run when the service starts. For example, you could set up the environment or call scripts.

Edit runsvc.sh.

Replace the following line with your instructions:

# insert anything to setup env when running as a service

Service Files

When you install the service, some service files are put in place.

.plist service file

A .plist service file is created:

~/Library/LaunchAgents/vsts.agent.{tfs-name}.{agent-name}.plist

For example:

~/Library/LaunchAgents/vsts.agent.fabrikam.our-osx-agent.plist

sudo ./svc.sh install generates this file from this template: ./bin/vsts.agent.plist.template

.service file

./svc.sh start finds the service by reading the .service file, which contains the path to the plist service file described above.

Alternative service mechanisms

We provide the ./svc.sh script as a convenient way for you to run and manage your agent as a launchd LaunchAgent service. But you can use whatever kind of service mechanism you prefer.

You can use the template described above as to facilitate generating other kinds of service files. For example, you modify the template to generate a service that runs as a launch daemon if you don't need UI tests and don't want to configure automatic log on and lock. See Apple Developer Library: Creating Launch Daemons and Agents.

Replace an agent

To replace an agent, follow the Download and configure the agent steps again.

When you configure an agent using the same name as an agent that already exists,
you're asked if you want to replace the existing agent. If you answer Y,
then make sure you remove the agent (see below) that you're replacing. Otherwise,
after a few minutes of conflicts, one of the agents will shut down.

Remove and re-configure an agent

Unattended config

The agent can be set up from a script with no human intervention.
You must pass --unattended and the answers to all questions.

To configure an agent, it must know the URL to your organization or collection and credentials of someone authorized to set up agents.
All other responses are optional.
Any command-line parameter can be specified using an environment variable instead:
put its name in upper case and prepend VSTS_AGENT_INPUT_.
For example, VSTS_AGENT_INPUT_PASSWORD instead of specifying --password.

Required options

--unattended - agent setup will not prompt for information, and all settings must be provided on the command line

Authentication options

--userName <userName> - specifies a Windows username in the format domain\userName or userName@domain.com

--password <password> - specifies a password

Pool and agent names

--pool <pool> - pool name for the agent to join

--agent <agent> - agent name

--replace - replace the agent in a pool. If another agent is listening by the same name, it will start failing with a conflict

Agent setup

--work <workDirectory> - work directory where job data is stored. Defaults to _work under the
root of the agent directory. The work directory is owned by a given
agent and should not share between multiple agents.

From the Agent pools tab, select the desired agent, and choose the Capabilities tab.

Look for the Agent.Version capability.

You can check this value against the latest published agent version. See Azure Pipelines Agent and check the page for the highest version number listed.

Each agent automatically updates itself when it runs a task that requires a newer version of the agent. But if you want to manually update some agents, right-click the pool, and then choose Update all agents.

Can I update my v2 agents that are part of an Azure DevOps Server pool?

Yes.
Beginning with Azure DevOps Server 2019, you can configure your the server to look for the agent package files on a local disk.
This will override the default version that came with the server at the time of its release.
This scenario also applies when the server does not have access to the Internet.

You're all set! Your Azure DevOps Server will now use the local files whenever the agents need to be updated. Each agent automatically updates itself when it runs a task that requires a newer version of the agent. But if you want to manually update some agents, right-click the pool, and then choose Update all agents.

For organizations using the dev.azure.com domain:

To ensure your organization works with any existing firewall or IP restrictions, ensure that dev.azure.com and *dev.azure.com are open and update your allow-listed IPs to include the following IP addresses, based on your IP version. If you're currently allow-listing the 13.107.6.183 and 13.107.9.183 IP addresses, leave them in place, as you don't need to remove them.

For organizations using the dev.azure.com domain:

To ensure your organization works with any existing firewall or IP restrictions, ensure that dev.azure.com and *dev.azure.com are open and update your allow-listed IPs to include the following IP addresses, based on your IP version. If you're currently allow-listing the 13.107.6.183 and 13.107.9.183 IP addresses, leave them in place, as you don't need to remove them.

IPv4 ranges

13.107.6.0/24

13.107.9.0/24

13.107.42.0/24

13.107.43.0/24

IPv6 ranges

2620:1ec:4::/48

2620:1ec:a92::/48

2620:1ec:21::/48

2620:1ec:22::/48

Note

This procedure enables the agent to bypass a web proxy. Your build pipeline and scripts must still handle bypassing your web proxy for each task and tool you run in your build.

For example, if you are using a NuGet task, you must configure your web proxy to support bypassing the URL for the server that hosts the NuGet feed you're using.

I'm using TFS and the URLs in the sections above don't work for me. Where can I get help?