Getting Started with Xcode Cloud

Learn how to use Xcode Cloud to test and deploy your app on TestFlight.

Xcode Cloud is Apple’s latest continuous integration and delivery service. With Xcode Cloud, you can test and distribute your apps through Apple’s servers. Best of all, it’s built right into Xcode!

This year, Apple released Xcode Cloud to all developers. Apple is offering 25 compute hours a month for free until December 2023.

In this Xcode Cloud tutorial, you’ll learn how to automate steps in your build process. You’ll run unit tests and create TestFlight builds any time code changes in your Git branch.

To follow along with the tutorial, you’ll need an Apple Developer account.

Why use Xcode Cloud?

Xcode Cloud is Apple’s implementation of Continuous Integration and Continuous Delivery, also known as CI/CD. Continuous Integration is a software development practice that allows you to merge several changes into a Git branch that maintains its stability through automated steps like unit tests. On the other hand, Continuous Delivery is a software development practice that allows you to automate most of your release process, which includes build and distribute to TestFlight.

Xcode Cloud allows you to create workflows to automate tasks you’d otherwise perform on your local machine. Xcode Cloud works with your Git repository on GitHub, GitLab or Bitbucket.

For example, you could create a workflow that builds your app and deploys to TestFlight when anyone on your team merges code to a specific Git branch.

TestFlight Xcode Cloud workflow

You won’t need to worry about manually distributing your app to team members and testers! Xcode Cloud takes care of all the heavy lifting to build and distribute your app, while your local machine is free to work on other features…or watch YouTube videos. :]

Getting Started

Download the starter project by clicking the Download Materials button at the top or bottom of the tutorial.

The materials contain a project called Coffee. The app tracks your favorite coffees or teas, along with tasting notes and a flavor profile.

Coffees list in the iPhone 14 simulator

Open the starter project. Build and run. The + button at the top right lets you add a new coffee, and tapping a coffee in the list lets you edit it.

In this tutorial, you’ll create Xcode Cloud workflows for the Coffee app.

First things first, though. Xcode Cloud requires a series of prerequisites before configuring your workflows.

Setting Up Prerequisites

Xcode Cloud requires two setup steps outside of Xcode:

  1. Enroll in the Apple Developer Program.
  2. Use a Git source code management tool to host your code.

First, you’ll need to enroll in the Apple Developer program. It’s OK if your membership is via a team in the Apple Developer program, as long as you can create a new app record.

Next, you’ll need a place to store your code. This tutorial stores code in GitHub, and all the references in the tutorial point to GitHub. Open a web browser and navigate to GitHub. Create an account on GitHub if you don’t already have one, then create a new repository.

Click the + in the top right of GitHub. Then, click New Repository to create the repository.

Action menu on GitHub

Your browser will direct you to a screen to enter repository details.

Create a new repository on GitHub

Enter Coffee as the repository name. Or, if you want to enter something else, go for it! The specific name isn’t relevant to Xcode Cloud. Leave all the other repository settings as the default values.

Note: Xcode Cloud supports GitHub, GitLab and Bitbucket. You’re welcome to use any of the three, but this tutorial will provide screenshots and walkthroughs for GitHub.

Finally, upload the Coffee starter project to the new GitHub repository. Follow the steps GitHub provides after creating your new repository. Start by opening Terminal and navigating to the starter project folder. Replace path_to_coffee_starter_project with your actual path!

cd path_to_coffee_starter_project

Then, create a Git repository in the Coffee starter project folder.

// 1
git init
git add .
git commit -m "first commit"
git branch -M main

git remote add origin [email protected]:your-username/Coffee.git

// 3
git push -u origin main

Here’s what’s happening in each command:

  1. Initialize the repo by copy and pasting the first four commands in Terminal.
  2. Add a reference to your git remote repository. Replace your-username with your GitHub username.
  3. Push the code to the remote repository.

You’re almost done setting up prerequisites. Only a couple more steps before you can unleash the power of Xcode Cloud!

Updating the Coffee App Project

Xcode Cloud requires two more setup steps:

  1. Add your Apple ID to Xcode.
  2. Set the bundle identifier for your app in Xcode.

First, sign in to Xcode using your Apple ID. Open preferences using Xcode ▸ Preferences, then navigate to Accounts. Click the + in the lower right, and add your Apple ID.

Add Apple ID account in Xcode

Xcode Cloud also requires you to set the bundle identifier in the Signing & Capabilities tab.

Open the Coffee starter project again. Navigate to the Coffee project settings. Select the Coffee target, and navigate to the Signing & Capabilities tab.

Xcode Signing & Capabilities tab

Next, you’ll update the Team and Bundle Identifier.

Xcode team and bundle identifier

For Team, select the team that matches your Apple Developer Program account. For Bundle Identifier, enter a bundle identifier in the following format: com.yourcompany.Coffee.

Xcode entered team and bundle identifier

Phew, that was quite a bit of setup. Now, on to the fun stuff! Xcode Cloud workflows are ready to enhance your project with the magic of CI/CD.

Creating Your First Workflow

Your first workflow is the default Xcode Cloud workflow. The default workflow builds your app when you merge code to the main branch. Xcode Cloud notifies you via email if the build fails.

Before you begin, you’ll have to change the app’s Product Name to a unique name. The name “Coffee” is unfortunately already taken. You can come up with something fun, though. Open the starter project in Xcode and navigate to Project ▸ Build Settings. Select Filter on the top right, and enter Product Name.

Xcode updated Product Name

Change the name to something no one else will think of. Try this format: Coffee[YourName][4-digit-number]. For example, CoffeeJoshBerlin5745. You won’t actually release this app, so the product name doesn’t matter much.

You’ll make two more changes using your new product name. First, open the Coffee project settings and select the CoffeeTests target.

Coffee test build settings

Select Filter on the top right and enter Test Host. You’ll filter the list of options to the Test Host values for the debug and release configurations.

Xcode Test Host configuration option

Xcode reads the Test Host path when running automated tests. You’ll need to update the path to use your new product name. Double-click the Debug test host value. Then, change the two references to Coffee to your new product name. Your new value will look like this, but with your name:

Xcode updated Test Host value

Next, open CoffeeViewModelTests.swift and change @testable import Coffee to your new name. Your new import will follow this format:

@testable import CoffeeJoshBerlin5745

Now that you have a unique product name, you can create your first workflow. Navigate to the Report Navigator.

Xcode navigate to Assistant Editor

The Report Navigator contains two tabs: Local and Cloud. Local displays all builds your computer runs locally. Cloud contains all builds Xcode Cloud runs in the cloud.

In the Cloud tab, click the Create Workflow button to create your first workflow.

Xcode select product in create workflow

Xcode Cloud works with apps and frameworks. Select your product and click Next.

Xcode review workflow

Xcode allows you to review the workflow before continuing. For now, leave all the settings as the defaults and click Next. Xcode Cloud contacts GitHub to check permissions.

Xcode grant access to source code

You haven’t set up any permissions yet, so Xcode Cloud asks you to grant access to your source code on GitHub. Click the Grant Access button to start the process.

Xcode opens App Store Connect in a web browser and prompts you to Connect Xcode Cloud with GitHub. Connecting is a two-step process:

  1. Link your Apple ID with your GitHub account.
  2. Install the Xcode Cloud app on your GitHub account.

Connect Xcode Cloud with GitHub

Click Complete Step 1 in GitHub to open GitHub and link your Apple ID. App Store Connect opens GitHub for authorization.

Grant Xcode Cloud GitHub permissions

Click Authorize Xcode Cloud to authorize Apple to link your Apple ID with GitHub. Now, GitHub prompts you to install the Xcode Cloud app.

Install Xcode Cloud on GitHub

Click Install to complete the authorization and installation process. GitHub redirects you back to App Store Connect.

Xcode installed on GitHub successfully

A green check mark means you’ve connected Xcode Cloud with GitHub! Apple even provides a handy button to re-open Xcode. Go ahead and click the Continue in Xcode button.

Back in Xcode, the grant access button is no longer available, and you’ll see another green check mark.

Xcode access granted to source code

Click Next to continue creating your first workflow. Xcode Cloud has GitHub permissions now, but it looks like you’ve hit a new roadblock!

Xcode Cloud create app on App Store Connect

Xcode Cloud requires an app on App Store Connect with your app’s bundle identifier. Lucky for you, Xcode can create the app without even opening a browser. Click Complete to create your app.

Xcode Cloud app created

The final green check mark means Xcode Cloud is ready for launch! At this point, you can create and run workflows.

Go ahead and click Start Build to kick off your very first Xcode Cloud build. Xcode Cloud immediately starts the build and switches to the build info in Xcode. Xcode Cloud also sends you an email when the build finishes. Congrats on your first Xcode Cloud build. :]

In the next section, you’ll set up a workflow to run the app’s unit and UI tests.

Creating a Workflow to Run Tests

Unit tests and user interface tests — also known as UI tests — are important to ensure you ship stable code. Whenever you change code in the main Git branch, it’s a good idea to run your test suite. Wouldn’t it be nice if your tests ran automatically when code changed?

Good news — Xcode Cloud is here to help! Xcode Cloud can run your tests on code changes, leaving your development machine free for other tasks.

Xcode Cloud automated tests workflow

The workflow you’ll configure in this section runs both the unit and UI tests whenever you update the main branch. Xcode Cloud builds your app and runs all your tests. You’ll receive a full report of the tests once they complete. The report shows which tests passed or failed, and it shows screenshots of any failed test.

The Coffee app has a suite of unit and UI tests. Open the Coffee starter project and navigate to CoffeeViewModelTests.swift. The CoffeeViewModel saves new coffees and updates existing coffees. The tests make sure your coffee is always saved properly. Run the test case using the diamond to the left of the test case name.

Xcode run unit tests

The tests in the test case run in the simulator. Once complete, the empty diamonds change to green check marks.

Xcode unit tests passed

Next, navigate to CoffeeUITests.swift. The CoffeeUITests contains one UI test to confirm the Add Coffee button works. Run the test using the diamond to the left of the test name.

Xcode run UI tests

The test runs in the simulator, and the empty diamond changes to a green check mark.

Xcode UI tests passed

Next, you’ll set up a workflow to run these tests. Navigate to the Report Navigator.

Xcode navigate to Report Navigator

In the previous section, you set up a default workflow that built the project. You can now edit it to run tests instead. Right-click Default and select Edit Workflow.

Xcode Cloud edit workflow

The Edit Workflow window is where you’ll find all the options to configure a workflow.

Xcode Cloud edit workflow overview

Edit Workflow contains a variety of configuration options:

  • General configures high-level options such as the workflow name and description.
  • Environment configures the Xcode and macOS versions for the build machine. You can also set environment variables for custom build scripts or test actions.
  • Start Conditions defines the conditions that trigger the workflow. You can trigger the workflow when code changes on a git branch, or when you create a Pull Request or Tag in GitHub. You can also trigger workflows on a specific schedule.
  • Actions defines the workflow steps, such as Build, Test, Analyze or Run.
  • Post-Actions defines any steps after the workflow completes. Workflows can deploy your app to TestFlight or notify via Slack or email on success or failure.

As you can see, Edit Workflow contains a lot of configuration options. For your unit and UI test workflow, you’ll focus on General and Actions. Navigate to General, and change the Name to Test.

Xcode Cloud change name of Test workflow

The workflow currently has an archive action in the Actions section. The test workflow only runs tests, so you can delete the archive action. Navigate to Archive – iOS and delete the action using the trash icon in the top right.

Xcode Cloud archive action in Test workflow

Next, add a test action using the + next to the Actions section title.

Xcode Cloud test workflow add test action

Select Test to add a test action.

Xcode Cloud test workflow test action added

The test action allows you to configure various options:

  • Platform defines which platform the tests run on. You can create a separate test action for each platform you want to test.
  • Scheme defines the scheme to use for the tests.
  • Requirement configures whether the tests need to pass or not. You want this workflow to fail if any tests fail, so Required To Pass is the right option.

The last section configures which devices the tests run on. Click the + to add iPads to your workflow.

Xcode Cloud add iPads to test action

Last, click Save to finish creating your test workflow.

Great job! You configured a workflow to run any time you change code on the main branch. Now no one can forget to run the tests, since Xcode Cloud will always run them for you :]

Testing the Test Workflow

In this section, you’ll put your new test workflow to the test. First, you’ll manually run the workflow. Then, you’ll update a test and watch Xcode Cloud start the workflow automatically.

Navigate to the Report Navigator and select the Cloud tab. Right-click main, and select Start Build to start the Test workflow on the main branch.

Xcode Cloud start Test workflow build

Select Start if Xcode asks you to confirm.

Xcode Cloud start Test workflow build

Note: Check the Don’t ask again checkbox if you’d like future builds to start without confirmation.

Xcode switches your view to the build overview. The overview shows the status of your build, including details and progress.

Xcode Cloud test build overview

The build runs on Apple’s build machines and runs the tests on various iPhone and iPad devices. This might take a few minutes. Grab a coffee or tea while you wait for the build to finish. :]

Xcode Cloud test build succeeded

After Xcode Cloud finishes your test build, Xcode updates to show a green check mark because all the tests passed! Next, you’ll add a unit and UI test to make sure saving a coffee with an empty name shows an error.

Open the CoffeeViewModelTests.swift file. At the end of CoffeeViewModelTests, add the following unit test:

func testSaveCoffeeWithEmptyName() async throws {
  // 1
  var coffeeToSave = CoffeeViewModel.newCoffee = ""

  do {
    // 2
    try await model.saveCoffee(coffeeToSave)
    XCTFail("Coffee with no name should throw empty name error")
  } catch CoffeeViewModel.CoffeeError.emptyName {
    // 3
    XCTAssertEqual(model.saveCoffeeError, .emptyName)
  } catch {
    // 4
    XCTFail("Coffee with no name should throw empty name error")

Here’s how the test works:

  1. You create a coffee to save using the default CoffeeViewModel.newCoffee. newCoffee is configured using default values when saving a new coffee. Next, you change the name to an empty string.
  2. You try to save the coffee with the empty name. The saveCoffee(_:) method is async and throws errors. So, you have to add try await before saving.
  3. You catch the specific CoffeeViewModel.CoffeeError.emptyName error from saveCoffee(_:). You also check that the view model’s showCoffeeErrorAlert is true. This means the view model is currently showing an error alert, and the saveCoffeeError value is .emptyName.
  4. The test fails for any other errors besides the emptyName error.

Open CoffeeUITests.swift and add this new UI test at the end of CoffeeUITests:

func testAddCoffeeWithNoNameShowsAlert() {
  // 1
  // 2

Here’s how the UI test works:

  1. On the Coffees screen, the test taps the + button to add a new coffee.
  2. On the Coffee Editor screen, the test taps the Save button to save the coffee. The default name is empty, so the coffee is saved without a name. Next, the test tries to close the Save Coffee error alert.

Note: CoffeesScreen and CoffeeScreen encapsulate the actions to perform the UI test. Browse CoffeesScreen.swift and CoffeeScreen.swift for a look at how they work.

Next, you’ll commit and push your new code to the main branch and watch Xcode Cloud run the tests. Open Terminal and navigate to the Coffee starter project folder. Run the following commands to commit and push your changes:

git commit -am "Adding a new unit and UI test"
git push -u origin main

Open the Coffee project and navigate to the Report Navigator. Select the Cloud tab.

Xcode Cloud test build running

Xcode Cloud automatically ran the Test workflow after you changed code on the main branch. Now, you can move on to the next section while Xcode Cloud runs your tests. :]

Creating a Workflow to Make TestFlight Builds

Xcode Cloud is a perfect match for TestFlight. Apple made it easy for developers to deploy builds to their teams with Xcode Cloud.

In this section, you’ll create a workflow to deploy a build to internal testers in TestFlight any time you push changes to the main branch. Before you start, you’ll need to create a group of internal testers in App Store Connect. Open a browser and navigate to your app in App Store Connect. Select the TestFlight tab.

TestFlight settings

The Internal Testing section on the left sidebar is empty. Click the + next to Internal Testing to add a new group.

TestFlight create new internal group

Enter Internal Testers as the name for your group. Leave Enable automatic distribution selected so the builds distribute to your testers without any extra steps. Click Create to create your new group.

TestFlight created a new internal group

Click the + next to Testers (0) and add yourself as a tester. Great! You now have a group of testers for your Xcode Cloud workflow. Now you’re ready to open Xcode to set up your new workflow.

Navigate to the Report Navigator. Select the Cloud tab. This time, you’ll create a new workflow just for your internal testers. Click the circle button at the bottom left and select Create Workflow.

Xcode Cloud create a new TestFlight workflow

Select your app product and click Next.

Xcode Cloud select a product for the TestFlight workflow

First, change the workflow Name to TestFlight. Next, check the Restrict Editing check box.

Xcode Cloud restrict editing

Apple requires restricted editing for any workflows with external deployments.

Note: You can find more information about restricted workflow in Apple’s documentation in the Restrict who can edit a workflow section.

Next, add an Archive action by clicking the + next to Actions and selecting Archive. Xcode Cloud adds an archive action for iOS by default.

Xcode Cloud add archive action

By default, the Platform is set to iOS, and the Scheme is set to Coffee — which is precisely what you want. For this workflow, you’ll deploy an app to your internal testers. Change the Deployment Preparation to TestFlight (Internal Testing Only).

Before starting an Xcode Cloud build with your new workflow, you’ll create a Post-Actions step to deploy the TestFlight build to a group of internal testers. Xcode Cloud runs the Post-Actions steps after the iOS archive is complete.

Xcode Cloud add internal testing post action

Click the + next to Post-Actions and select TestFlight Internal Testing. Xcode Cloud adds the post-action, but displays a red X. The post-action does not contain any beta groups, so the action displays an error.

Xcode Cloud add internal test group to the post action

Click the + in the Groups section, and select your new Internal Testers group. Your group has one tester — you!

Xcode Cloud add internal testing group to the archive action

Click Add to add your group to the internal TestFlight deployment.

Xcode Cloud TestFlight workflow group added

Now, the workflow deploys a build to the Internal Testers group when the workflow runs. Click Save to create your new workflow.

Instead of pushing new code, you’ll manually run the workflow to test the deployment. Right-click your new TestFlight workflow and select Start Build.

Xcode Cloud start TestFlight build

Since you started the build manually, you’ll need to select a branch. Xcode Cloud displays a window for you to select the branch.

Xcode Cloud my branches filter

Switch the filter from Mine to All to display all the branches.

Xcode Cloud all branches filter

Select the main branch, and click Start Build. Now, sit back and relax while Xcode Cloud does all the work to create your new TestFlight build.

Xcode Cloud TestFlight workflow succeeded

After Xcode Cloud completes the build, you’ll receive an invite email from TestFlight. Accept the invite, and install your new app!

Where to Go From Here?

Download the completed project files by clicking the Download Materials button at the top or bottom of the tutorial.

Apple’s Xcode Cloud documentation is a good place to go if you’d like to learn more. You’ll find an article about setting up Xcode Cloud for your team. You’ll find another article about connecting Xcode Cloud to Slack.

We hope you enjoyed this tutorial. If you have any questions or comments, please join the forum discussion below!

Source link

Leave a Reply