Skip to content
Back to Blog
·9 min read

Xcode Cloud for a small team: workflows and compute hours

What an Xcode Cloud workflow is, start conditions, build/test/analyze/archive actions, TestFlight and notify post-actions, ci_scripts, CI_ variables, compute hours and logs.

Xcode Cloud is Apple's build service inside Xcode and App Store Connect. You describe a workflow (what to build, when, on which Xcode and macOS, and what to do afterwards) and Apple's servers build, test and archive your app when you push, open a pull request, tag a release, on a schedule or when you press Start Build. Apple Developer Program membership includes 25 compute hours per month; paid plans add 100, 250, 1,000 or 10,000 hours (prices below, as read on 1 November 2026). Logs and artifacts are kept for up to 30 days, so download anything you ship to the App Store.

Before you start

From Apple's "Get started" and setup pages:

  • You need Xcode 15.0 or later and Apple Developer Program membership.
  • The first setup has to happen in Xcode (Report navigator, Cloud button, Get Started). After the first build you can edit and create workflows in Xcode or in the Xcode Cloud tab of your app in App Store Connect.
  • Setting up a workflow can be done by the Account Holder, an Admin or an App Manager, or a Developer or Marketing user who may create app records.
  • Supported Git hosts: Bitbucket Cloud and Server, GitHub and GitHub Enterprise, GitLab and self-managed GitLab. You need admin-level permission on the repository host to grant access.
  • Apple warns that if a tool generates or edits your project or workspace on the fly, "the initial configuration of Xcode Cloud and subsequent builds may fail." The project needs to be in the repository as-is.

What a workflow is

Apple: "The workflow is the configuration for the steps you want Xcode Cloud to perform." Each workflow has:

  • General: a name and description. Apple suggests clear names such as "Nightly Builds", even for a solo developer with several workflows.
  • Environment: the Xcode and macOS versions, an optional Clean build (no cached data), and custom environment variables.
  • Start conditions: what starts a build.
  • Actions: build, test, analyze, archive.
  • Post-actions: notify, TestFlight, upload for App Store review.

Apple's suggested split for a small team: one workflow that builds and tests on every branch or pull request change, and a second one that builds, tests, analyzes and archives when you merge into main.

Two environment details worth knowing:

  • Builds reuse cached derived data. A workflow that sends builds to external TestFlight testers needs Clean turned on, and Apple notes this "significantly increases the time it takes to perform a build."
  • Apple "may update available macOS and Xcode versions and subsequently ask you to update your workflows." The build machines include macOS and Xcode tools, plus Homebrew for third-party tools.

Start conditions

Start conditionA build starts when
Branch ChangesAny branch, one branch, several branches, or branches beginning with a prefix change
Pull Request ChangesA pull request is opened or updated (filter by source and target branch)
Tag ChangesA tag is created or updated (any tag, named tags, or tags beginning with a prefix such as v1)
On a Schedule for a BranchAt the frequency, time and branch you choose
Manual StartSomeone on the team presses Start Build, for the branches, tags or pull requests you allow

Details from Apple's page:

  • A new workflow starts with Branch Changes on the default branch. Apple points out this can be too often for slow workflows, such as UI tests on many simulators.
  • For a pull request, Xcode Cloud checks out the source and target branches, merges them in a temporary environment and runs the actions on the result.
  • Files and folders filters: for branch, pull request and tag conditions you can start a build only when certain files, folders or file extensions change, or skip a build for them. One condition can start or skip, not both, and file names can't contain a wildcard such as *.
  • Skip one push: put [ci skip] in the title or message of the latest commit you push.
  • Auto-cancel Builds is on by default: if a new build is queued for the same workflow, the one in progress is cancelled. You can turn it off per start condition.
  • Apple suggests a schedule (for example once a week) for TestFlight builds rather than every change, so testers aren't flooded.

Actions

ActionWhat runsArtifacts Apple lists
Buildxcodebuild build for a platform and scheme, any device or any simulatorBuild product, build logs, result bundle
Testxcodebuild build-for-testing, then test-without-building on the destinations you addTest products and result bundle
Analyzexcodebuild analyze (static analysis)Build logs
Archivexcodebuild archiveExported archive or framework bundle, build logs
  • A test action builds for testing itself, so you don't need a separate build action to run tests. More test destinations means a longer build.
  • Test and analyze can be Required to Pass or Not Required to Pass.
  • Each action runs in its own temporary environment, so one action's files may not be available to another.
  • The archive action's Deployment Preparation decides signing: None (not for TestFlight or the App Store), TestFlight (Internal Testing Only), or TestFlight and App Store. Builds for external testers and release need the last one.

Post-actions

After the actions finish, a workflow can:

  • Notify: limit email to certain build results, email more people, or post to Slack (Apple's Slack app; channel per workflow or direct messages; connecting it needs the App Manager, Admin or Account Holder role in App Store Connect).
  • TestFlight: send the build to internal or external testers. Create the internal tester group in App Store Connect first. Builds for external groups still go through TestFlight App Review; see our TestFlight checklist.
  • App Store Connect: upload a version you can later submit for review.

Custom build scripts

Put shell scripts in a folder named ci_scripts next to your .xcodeproj or .xcworkspace. Only three names are recognised, at the top level of that folder:

FileRuns
ci_post_clone.shAfter the repository is cloned (install a tool, edit a plist)
ci_pre_xcodebuild.shBefore xcodebuild
ci_post_xcodebuild.shAfter xcodebuild, even if it failed (upload artifacts somewhere)

The scripts run for every action. Rules from Apple:

  • Make them executable (chmod +x) and start with a shebang such as #!/bin/sh. Otherwise they run as zsh $filename, which can fail the build.
  • No sudo.
  • Files a script creates are deleted afterwards, aren't visible to the other scripts and aren't in the downloadable artifacts.
  • Your source code may not be available while a script runs, so keep resources the scripts need inside ci_scripts (or a symbolic link there).
  • Exit with a nonzero code when something goes wrong; Apple's example uses set -e. A nonzero exit fails the build.
  • Helper scripts can live in ci_scripts too; Apple suggests not starting their names with ci_.

Environment variables

Your own variables go in the workflow's Environment section. Tick Keep value redacted (Xcode) or Secret (App Store Connect) for keys and tokens; secret values show as ******* in logs. Shared* environment variables can be applied to several workflows and edited in one place, optionally restricted to the Account Holder.

Predefined variables Apple lists as always available include:

VariableValue
CI, CI_XCODE_CLOUDTRUE when running in Xcode Cloud
CI_BUILD_NUMBER, CI_BUILD_ID, CI_BUILD_URLBuild number, unique ID, link to the build in App Store Connect
CI_COMMITGit commit hash being built
CI_WORKFLOW, CI_WORKFLOW_IDWorkflow name and ID
CI_START_CONDITIONmanual, manual_rebuild, push, pr_open, pr_update or schedule
CI_PRODUCT_PLATFORMiOS, macOS, tvOS or watchOS
CI_XCODEBUILD_ACTIONanalyze, archive, build, build-for-testing or test-without-building
CI_XCODEBUILD_EXIT_CODEExit code of xcodebuild, after it ran
CI_PRIMARY_REPOSITORY_PATH, CI_WORKSPACE_PATHWhere the source and workspace are, e.g. /Volumes/workspace/repository
CI_BUNDLE_ID, CI_TEAM_ID, CI_XCODE_SCHEME, CI_DERIVED_DATA_PATHAs named

Others depend on what started the build or which action runs: CI_BRANCH, CI_TAG, CI_GIT_REF; CI_PULL_REQUEST_NUMBER and the other CI_PULL_REQUEST_ values; CI_RESULT_BUNDLE_PATH, CI_TEST_PLAN and other test values; CI_ARCHIVE_PATH and the CI__SIGNED_APP_PATH paths for archives. In test actions, your variables reach the test runner with a TEST_RUNNER_ prefix added by Xcode Cloud. The build machines also set HTTP_PROXY and HTTPS_PROXY.

Compute hours and plans

As read on Apple's Xcode Cloud pages on 1 November 2026:

PlanCompute hours per monthPrice
Included with Apple Developer Program25Included
Paid100US$49.99/month
Paid250US$99.99/month
Paid1,000US$399.99/month
Paid10,000US$3,999.99/month
  • What counts. Apple: "A compute hour is an hour of time used to execute a specific task in the cloud, such as building an app or running" tests, and "running 5 tests of 12 minutes each equals one compute hour." Because actions run in parallel, the time a build takes and the usage it reports differ.
  • Unused hours "don't roll over to the next month."
  • Who buys. Only the Account Holder, in the Account tab of the Apple Developer app, and only after a workflow has been set up. Plans are priced in US dollars, or local currency where available.
  • Upgrading starts a new billing period: "Your quota resets to 0 and the number of compute hours is replaced based on the new subscription." Downgrading keeps the current plan until the period ends. Cancelling a paid plan keeps the remaining hours for the period, then you're back to 25.
  • Opting out of Xcode Cloud after cancelling makes your products, workflows and builds inaccessible, and they "cannot be restored."
  • Tracking usage: App Store Connect, Users and Access, Xcode Cloud tab (team) or an app's Xcode Cloud tab (per app), with trends and a .csv export; also the Apple Developer app's Account tab.

Apple's pages don't say what happens to a build that is running when you hit the monthly limit, and don't list how many builds can run at once on each plan.

Where logs and artifacts are

  • Xcode: Report navigator, Cloud button, select a build. Expand an action in the report outline and click Logs; click Artifacts to download the build report and other files.
  • App Store Connect: your app, Xcode Cloud tab, Builds; expand an action in the sidebar and click Logs.
  • What's stored: build information, app binaries, symbol information, test results and more.
  • For how long: "Xcode Cloud stores artifacts for up to 30 days after it completes a build." Apple asks you to download and archive artifacts for every version you release, because you need the symbol information to read crash reports later.
  • Deleting a workflow deletes its build history and artifacts. To keep them, deactivate the workflow instead.
  • Output from your ci_scripts appears in the build logs.

A small-team starting setup

Based on Apple's own suggestions:

  1. Checks: Branch Changes plus Pull Request Changes, one test action with one or two simulators, Auto-cancel on, a files filter so documentation edits don't start a build.
  2. Testers: On a Schedule for main (weekly or nightly), archive with TestFlight (Internal Testing Only), TestFlight post-action to your internal group, Notify to Slack or email.
  3. Release: Tag Changes for tags beginning with v, Clean on, archive with TestFlight and App Store, then download the artifacts within 30 days.

Watch the usage page during the first month to see whether 25 hours is enough before buying a plan.

FAQ

Can I set up Xcode Cloud only from App Store Connect?

No. Apple says the first configuration has to be done in Xcode; after the first build, workflows can be managed from either.

Does Xcode Cloud upload builds to TestFlight for me?

Yes, with an archive action and a TestFlight post-action. Apple: "Xcode Cloud archives the build and uploads it to App Store Connect for you." External testers still need TestFlight App Review and a TestFlight and App Store archive.

How do I stop one push from starting a build?

Include [ci skip] in the title or message of the latest commit you push.

Do unused compute hours carry over?

No. Apple: unused compute hours "don't roll over to the next month."

How long can I download artifacts?

Up to 30 days after the build completes.

Sources

All read on 1 November 2026.

Apple's plans, prices and Xcode Cloud settings change; check the pages above for current details.

Written by

Building local-first Mac & iOS productivity apps at Obelisk Club. About the author →