Add macOS to your continuous integration pipelines with AWS CodeBuild

Add macOS to your continuous integration pipelines with AWS CodeBuild

Spoken by Polly

Starting today, you can use AWS CodeBuild to build applications on macOS. You can now build artifacts on managed Apple M2 machines running macOS 14 Sonoma. AWS CodeBuild is a fully managed continuous integration service that compiles source code, runs tests, and creates ready-to-use software packages.

Building, testing, signing, and distributing applications for Apple systems (iOS, iPadOS, watchOS, tvOS, and macOS) requires Xcode, which runs exclusively on macOS. If you build applications for Apple systems in the AWS Cloud, you’ve most likely configured your continuous integration and continuous deployment (CI/CD) pipeline to run on Amazon Elastic Cloud Compute (Amazon EC2) Mac instances.

Since we launched Amazon EC2 Mac in 2020, I’ve spent a lot of time with our customers across industries and geographies, helping them configure and optimize their pipelines on macOS. In its simplest form, a customer’s pipeline might look like the diagram below.

iOS build pipeline on EC2 Mac

The pipeline starts when there is a new commit or pull request in the source code repository. The repository agent installed on the machine triggers various scripts to configure the environment, build and test the application, and finally deploy it to App Store Connect.

Amazon EC2 Mac makes managing and automating macOS machines much easier. I like to describe it like this: An EC2 Mac instance provides everything I love about Amazon EC2 (Amazon Elastic Block Store (Amazon EBS) volumes, snapshots, virtual private clouds (VPCs), security groups, and more) on Mac Minis running macOS in the cloud.

However, customers face two challenges. The first is to prepare the Amazon Machine Image (AMI) with all the necessary tools for the build. A minimal build environment requires Xcode, but it is very common to install Fastlane (and Ruby) as well as other build or development tools and libraries. Most organizations need multiple build environments for multiple combinations of macOS and Xcode versions.

The second challenge is scaling your build fleet according to the number and duration of builds. Large organizations typically have hundreds or thousands of builds per day, which requires dozens of build machines. Scaling this fleet helps save costs. EC2 Mac instances are reserved for your dedicated use. An instance is assigned to a dedicated host. Scaling a fleet of dedicated hosts requires specific configuration.

To address these challenges and simplify the configuration and management of your macOS build machines, today we are introducing CodeBuild for macOS.

CodeBuild for macOS is built on the recently introduced Reserved Capacity Fleet, which includes Amazon EC2-powered instances managed by CodeBuild. With Reserved Capacity Fleets, you configure a set of dedicated instances for your build environment. These machines remain idle and are ready to process builds or tests immediately, reducing build time. With Reserved Capacity Fleets, your machines are always running and continue to incur costs as long as they are provisioned.

CodeBuild provides a standard disk image (AMI) to run your builds. It includes pre-installed versions of Xcode, Fastlane, Ruby, Python, Node.js, and other popular tools for a development and build environment. The full list of installed tools can be found in the documentation. Over time, we will provide additional disk images with updated versions of these tools. You can also bring your own custom disk image if you want.

Additionally, CodeBuild makes it easy to configure auto-scaling. You tell us how much capacity you need and we manage everything from there.

Let’s see CodeBuild for macOS in action
To show you how it works, I’ll create a CI/CD pipeline for my favorite project: Getting Started with AWS Amplify on iOS. This tutorial and accompanying source code explain how to build a simple iOS app with a cloud-based backend. The app uses a GraphQL API (AWS AppSync), a NoSQL database (Amazon DynamoDB), file-based storage (Amazon Simple Storage Service (Amazon S3)), and user authentication (Amazon Cognito). AWS Amplify for Swift is the piece that ties all these services together.

The tutorial and source code of the app are available in a Git repository. It contains scripts to automate the building, testing and deployment of the app.

Configuring a new CI/CD pipeline with CodeBuild for macOS involves the following general steps:

  1. Create the build project.
  2. Create a dedicated machine park.
  3. Configure one or more build triggers.
  4. Add a pipeline definition file (buildspec.yaml) to the project.

To get started, I open the AWS Management Console, select CodeBuild, and select Create project.

Code Build Mac - 1

I enter a Project name and configure the connection to the source Code repository. In this example, I’m using GitHub. CodeBuild also supports GitLab and BitBucket. The documentation contains an up-to-date list of supported source code repositories.

Code Build Mac - 2

For the Deployment modelI choose Reserved capacity. This is the only model where Amazon EC2 Mac instances are available. I have not defined a fleet yet, so I decide to create one while creating the build project. I choose Create fleet.

Code Build Mac - 3

On the Configuring the compute fleet Page I enter Calculate fleet names and select macOS as operating system. Under CalculateI select the amount of memory and the number of vCPUs I need for my build project, as well as the number of instances I want to capacity.

For this example I like to use the Managed image. It includes Xcode 15.4 and the Simulator Runtime for iOS 17.5, among others. The list of packages preinstalled on this image can be found in the documentation.

When I’m done, I choose Create fleet to return to the CodeBuild project creation page.

CodeBuild - Create Fleet

As a next step, I tell CodeBuild to create a new service role to define the permissions I want for my build environment. As part of this project, I need to include permissions to get an Amplify configuration and access AWS Secrets Manager. I’m not sharing a step-by-step guide on how to do this, but the sample project code includes the list of permissions I added.

Code Build Mac - 4

I can choose to define my set of build commands in the project definition or in a buildspec.yaml File included in my project. I choose the latter.

Code Build Mac – 5

This is optional, but I want to upload the build artifact to an S3 bucket where I can archive each build. In Artifact 1 – Primary Section, I therefore choose AmazonS3 as typeand enter Bucket name and artifact nameThe file name to be uploaded is shown in the buildspec.yaml File.

Code Build Mac – 6

At the bottom of the page, I configure the project trigger to add a GitHub WebHook. This will configure CodeBuild to start the build every time a commit or pull request is submitted to my project on GitHub.

Codebuild - Webhook

Finally, I choose the orange Create project button at the bottom of the page to create this project.

Testing my builds
My project already contains build scripts to prepare the build, build the project, run the tests, and deploy it to Apple’s TestFlight.

Codebuild – Project scripts

I add buildspec.yaml File in the root directory of my project to orchestrate these existing scripts.

version: 0.2

phases:

  install:
    commands:
      - code/ci_actions/00_install_rosetta.sh
  pre_build:
    commands:
      - code/ci_actions/01_keychain.sh
      - code/ci_actions/02_amplify.sh
  build:
    commands:
      - code/ci_actions/03_build.sh
      - code/ci_actions/04_local_tests.sh
  post_build:
    commands:
      - code/ci_actions/06_deploy_testflight.sh
      - code/ci_actions/07_cleanup.sh
artifacts:
   name: $(date +%Y-%m-%d)-getting-started.ipa
   files:
    - 'getting started.ipa'
  base-directory: 'code/build-release'

I add this file to my Git repository and push it to GitHub with the following command: git commit -am "add buildpsec" buildpec.yaml

On the console I can see that the build has started.

Codebuild - Build history

When I select the build, I can see or select the log files Phase details to get a general status of each phase of the build.

Codebuild – Phase Details

If the build is successful, I can see the iOS application IPA file uploaded to my S3 bucket.

aws s3 ls

The final build script that CodeBuild runs uploads the binary to App Store Connect. I can observe new builds in the TestFlight section of App Store Connect.

App Store Connect

What you should know
It takes 8-10 minutes to prepare an Amazon EC2 Mac instance and accept the very first build. This is not specific to CodeBuild. The builds you submit during the machine preparation time are queued and run in order as soon as the machine is available.

CodeBuild for macOS works with reserved fleets. Unlike on-demand fleets where you pay per build minute, reserved fleets are charged for the time the build machines are reserved for your exclusive use, even when no builds are running. Capacity reservation follows the 24-hour minimum allocation period for Amazon EC2 Mac as required by the Software License Agreement for macOS (Article 3.A.ii).

A fleet of machines can be shared across multiple CodeBuild projects in your AWS account. The machines in the fleet are reserved for your exclusive use. Only CodeBuild can access the machines.

CodeBuild cleans up the working directory between builds, but the machines are reused for other builds. You can use CodeBuild’s local cache mechanism to quickly restore selected files after a build. If you build different projects on the same fleet, you must reset all global states (such as the macOS keychain) and build artifacts (such as the SwiftPM and Xcode package caches) before starting a new build.

If you are working with custom build images, make sure they are built for a 64-bit Mac Arm architecture. You must also install and start the AWS Systems Manager Agent (SSM Agent). CodeBuild uses the SSM Agent to install its own agent and manage the machine. Finally, make sure the AMI is available for the CodeBuild organization ARN.

CodeBuild for macOS is available in the following AWS Regions: US East (Ohio, N. Virginia), US West (Oregon), Asia Pacific (Sydney), and Europe (Frankfurt). These are the same regions that offer Amazon EC2 Mac M2 instances.

Get started today and create your first CodeBuild project on macOS.

— seb

Leave a Reply

Your email address will not be published. Required fields are marked *