---
description: Bitbucket Pipelines has no hosted macOS runners. Here's how to build, sign, and ship iOS apps from your Bitbucket pipeline using Capawesome Cloud and its CLI.
title: Build & Ship iOS Apps with Bitbucket Pipelines - Capawesome
image: https://capawesome.io/docs/assets/images/social/blog/build-and-deploy-ios-apps-with-bitbucket.png
---

<!doctype html> 

[Skip to content ](#build-ship-ios-apps-with-bitbucket-pipelines) 

[📲 Introducing **Build Sharing** — get your builds onto testers' devices with a link & QR code. No account required. ](/blog/share-mobile-app-builds-with-testers/) 

* [ SDKs ](/docs/sdks/)
* [ Formbricks ](/docs/sdks/capacitor/formbricks/)
* [ Geocoder ](/docs/sdks/capacitor/geocoder/)
* [ Google Sign-In ](/docs/sdks/capacitor/google-sign-in/)
* [ Grafana Faro ](/docs/sdks/capacitor/grafana-faro/)
* [ Gyroscope ](/docs/sdks/capacitor/gyroscope/)
* [ Haptics ](/docs/sdks/capacitor/haptics/)
* [ Home Indicator ](/docs/sdks/capacitor/home-indicator/)
* [ In-App Browser ](/docs/sdks/capacitor/in-app-browser/)
* [ Install Referrer ](/docs/sdks/capacitor/install-referrer/)
* [ Intercom ](/docs/sdks/capacitor/intercom/)
* [ Intune ](/docs/sdks/capacitor/intune/)
* [ Keep Awake ](/docs/sdks/capacitor/keep-awake/)
* [ libSQL ](/docs/sdks/capacitor/libsql/)
* [ Light Sensor ](/docs/sdks/capacitor/light-sensor/)
* [ Live Update ](/docs/sdks/capacitor/live-update/)
* [ Localization ](/docs/sdks/capacitor/localization/)
* [ Mail Composer ](/docs/sdks/capacitor/mail-composer/)
* [ Managed Configurations ](/docs/sdks/capacitor/managed-configurations/)
* [ Maps Launcher ](/docs/sdks/capacitor/maps-launcher/)
* [ Media Session ](/docs/sdks/capacitor/media-session/)
* [ ML Kit ](/docs/sdks/capacitor/mlkit/)
* [ Navigation Bar ](/docs/sdks/capacitor/navigation-bar/)
* [ Network ](/docs/sdks/capacitor/network/)
* [ NFC ](/docs/sdks/capacitor/nfc/)
* [ Node.js ](/docs/sdks/capacitor/nodejs/)
* [ OAuth ](/docs/sdks/capacitor/oauth/)
* [ Passkeys ](/docs/sdks/capacitor/passkeys/)
* [ Password Autofill ](/docs/sdks/capacitor/password-autofill/)
* [ PDF Generator ](/docs/sdks/capacitor/pdf-generator/)
* [ PDF Viewer ](/docs/sdks/capacitor/pdf-viewer/)
* [ Pedometer ](/docs/sdks/capacitor/pedometer/)
* [ Permissions ](/docs/sdks/capacitor/permissions/)
* [ Phone Dialer ](/docs/sdks/capacitor/phone-dialer/)
* [ Photo Editor ](/docs/sdks/capacitor/photo-editor/)
* [ Photo Manipulator ](/docs/sdks/capacitor/photo-manipulator/)
* [ PixLive ](/docs/sdks/capacitor/pixlive/)
* [ PostHog ](/docs/sdks/capacitor/posthog/)
* [ Printer ](/docs/sdks/capacitor/printer/)
* [ Privacy Screen ](/docs/sdks/capacitor/privacy-screen/)
* [ Proximity Sensor ](/docs/sdks/capacitor/proximity-sensor/)
* [ Purchases ](/docs/sdks/capacitor/purchases/)
* [ RealtimeKit ](/docs/sdks/capacitor/realtimekit/)
* [ Root Detection ](/docs/sdks/capacitor/root-detection/)
* [ Screen Brightness ](/docs/sdks/capacitor/screen-brightness/)
* [ Screen Orientation ](/docs/sdks/capacitor/screen-orientation/)
* [ Screen Reader ](/docs/sdks/capacitor/screen-reader/)
* [ Screenshot ](/docs/sdks/capacitor/screenshot/)
* [ Secure Preferences ](/docs/sdks/capacitor/secure-preferences/)
* [ Settings Launcher ](/docs/sdks/capacitor/settings-launcher/)
* [ Shake ](/docs/sdks/capacitor/shake/)
* [ Silent Mode ](/docs/sdks/capacitor/silent-mode/)
* [ SIM ](/docs/sdks/capacitor/sim/)
* [ SMS Composer ](/docs/sdks/capacitor/sms-composer/)
* [ Speech Recognition ](/docs/sdks/capacitor/speech-recognition/)
* [ Speech Synthesis ](/docs/sdks/capacitor/speech-synthesis/)
* [ Share Target ](/docs/sdks/capacitor/share-target/)
* [ Square Mobile Payments ](/docs/sdks/capacitor/square-mobile-payments/)
* [ SQLite ](/docs/sdks/capacitor/sqlite/)
* [ Superwall ](/docs/sdks/capacitor/superwall/)
* [ System WebView ](/docs/sdks/capacitor/system-webview/)
* [ Tauri ](/docs/sdks/capacitor/tauri/)
* [ Text Interaction ](/docs/sdks/capacitor/text-interaction/)
* [ Text Zoom ](/docs/sdks/capacitor/text-zoom/)
* [ Thermal State ](/docs/sdks/capacitor/thermal-state/)
* [ Toast ](/docs/sdks/capacitor/toast/)
* [ Torch ](/docs/sdks/capacitor/torch/)
* [ Vault ](/docs/sdks/capacitor/vault/)
* [ Volume ](/docs/sdks/capacitor/volume/)
* [ Wallet ](/docs/sdks/capacitor/wallet/)
* [ Wifi ](/docs/sdks/capacitor/wifi/)
* [ YouTube Player ](/docs/sdks/capacitor/youtube-player/)
* [ Zip ](/docs/sdks/capacitor/zip/)
* [ Cordova ](/docs/sdks/cordova/)
* [ Cloud ](/docs/cloud/)
* [ Integrations ](/docs/cloud/live-updates/integrations/)
* Concepts
* Reference
* [ Troubleshooting ](/docs/cloud/live-updates/troubleshooting/)
* [ FAQ ](/docs/cloud/live-updates/faq/)
* [ Native Builds ](/docs/cloud/native-builds/)
* [ Set Up Environments ](/docs/cloud/native-builds/environments/)
* [ Set Up Native Configurations ](/docs/cloud/native-builds/native-configurations/)
* [ Auto-Increment Build Numbers ](/docs/cloud/native-builds/auto-incrementing-build-numbers/)
* [ Configure the Web Build Script ](/docs/cloud/native-builds/web-build-script/)
* [ Build from a Monorepo ](/docs/cloud/native-builds/monorepo/)
* [ Use pnpm, Yarn, or bun ](/docs/cloud/native-builds/package-managers/)
* [ Install Private npm Packages ](/docs/cloud/native-builds/npm-private-registry/)
* [ Override the Java Version ](/docs/cloud/native-builds/override-java-version/)
* [ Custom iOS Provisioning Profiles ](/docs/cloud/native-builds/custom-ios-provisioning-profiles/)
* [ Build without Git ](/docs/cloud/native-builds/build-without-git/)
* [ Access Git Behind a Firewall ](/docs/cloud/native-builds/firewall-access/)
* [ Integrations ](/docs/cloud/native-builds/integrations/)
* Reference
* [ Troubleshooting ](/docs/cloud/native-builds/troubleshooting/)
* [ FAQ ](/docs/cloud/native-builds/faq/)
* [ App Store Publishing ](/docs/cloud/app-store-publishing/)
* [ Submit a Build ](/docs/cloud/app-store-publishing/submit-a-build/)
* [ Submit Automatically After a Build ](/docs/cloud/app-store-publishing/submit-automatically/)
* [ Troubleshooting ](/docs/cloud/app-store-publishing/troubleshooting/)
* [ FAQ ](/docs/cloud/app-store-publishing/faq/)
* [ Automations ](/docs/cloud/automations/)
* [ Reference ](/docs/cloud/automations/reference/)
* [ Troubleshooting ](/docs/cloud/automations/troubleshooting/)
* [ FAQ ](/docs/cloud/automations/faq/)
* [ Assist ](/docs/cloud/assist/)
* [ CLI ](/docs/cloud/cli/)
* APIs and SDKs
* [ Webhooks ](/docs/cloud/webhooks/)
* [ Integrations ](/docs/cloud/integrations/)
* Notifications
* Account
* [ Organization ](/docs/cloud/organizations/)
* [ Two-Factor Enforcement ](/docs/cloud/organizations/two-factor-authentication/)
* [ Audit Logs ](/docs/cloud/organizations/audit-logs/)
* [ Billing ](/docs/cloud/organizations/billing/)
* [ License Keys ](/docs/cloud/license-keys/)
* [ AI ](/docs/ai/)
* [ Insiders ](/docs/insiders/)
* [ Billing & Plans ](/docs/insiders/billing-and-plans/)
* [ FAQ ](/docs/insiders/faq/)
* [ License ](https://capawesome.io/legal/eula/)
* [ Support ](/docs/support/)
* [ Contributing ](/docs/contributing/)
* Contributing code
* [ Code of Conduct ](/docs/contributing/code-of-conduct/)
* [ Questions ](https://docs.github.com/en/discussions/collaborating-with-your-community-using-discussions/participating-in-a-discussion#creating-a-discussion)
* [ Blog ](/blog/)
* Categories

* [ Related Posts ](#related-posts)
* [ Get Started ](#get-started)
* [ Conclusion ](#conclusion)

# Build & Ship iOS Apps with Bitbucket Pipelines[¶](#build-ship-ios-apps-with-bitbucket-pipelines "Permanent link")

Bitbucket Pipelines is a solid CI/CD home for your backend, your web app, and your tests. Then you try to build your iOS app and hit a wall: Atlassian's hosted runners are Linux containers, and there's no macOS image to pick. iOS builds need Xcode, and Xcode needs a Mac. This guide shows you how to close that gap — building, signing, and shipping iOS apps straight from your existing Bitbucket pipeline, without owning a single Mac.

[ ![Build and deploy your Capacitor app with Capawesome Cloud](https://capawesome.io/assets/banners/cloud-build-and-deploy-capacitor-apps.png?t=1) ](https://capawesome.io/) 

This works whether your app is a native Swift or Objective-C project, a [Capacitor](https://capawesome.io/integrations/capacitor/) app, or a Cordova app. The build itself happens on real macOS hardware in the cloud — your Bitbucket pipeline just kicks it off.

## The Bitbucket + iOS Problem[¶](#the-bitbucket-ios-problem "Permanent link")

Bitbucket Pipelines runs every step inside a Docker container on Linux. That's perfect for `npm`, `gradle`, `pytest`, and most of what a team does day to day. It's also a hard stop for iOS: you can't run `xcodebuild` without macOS and Xcode, and Atlassian doesn't offer hosted macOS runners.

So teams that live in Bitbucket usually end up with their iOS build sitting _somewhere else_ — a Mac mini under a desk, or a second CI tool bolted on just for mobile. Now you're maintaining two pipelines, two sets of secrets, and two mental models for "how do we ship."

The goal is simple: keep Bitbucket as the place your team already pushes code, and make iOS builds a normal step in that pipeline.

## Your Options for macOS[¶](#your-options-for-macos "Permanent link")

There are three realistic ways to get a macOS build out of a Bitbucket-centric setup.

**1\. Run a self-hosted macOS runner.** Bitbucket supports self-hosted runners, so you can register a Mac and point your pipeline at it. It works — until the Mac needs an OS update, Xcode falls behind, a certificate expires in Keychain, or the machine simply goes offline on a Friday. You've traded a CI problem for an IT problem.

**2\. Add a separate mobile-only CI tool.** Wire up a second platform purely for the iOS build. This solves the macOS problem but splits your pipeline in two, with duplicated triggers, secrets, and notifications to keep in sync.

**3\. Trigger cloud macOS builds from Bitbucket.** Keep Bitbucket Pipelines as the orchestrator and hand the actual iOS build off to a cloud service running real Macs. One command in your existing pipeline; no hardware to babysit.

For most teams, the third option is the one worth recommending. You don't give up Bitbucket, you don't maintain a Mac, and the iOS build stays a first-class step next to everything else. That's what the rest of this guide walks through, using [Capawesome Cloud](https://capawesome.io/).

## How It Works[¶](#how-it-works "Permanent link")

The model is a clean split of responsibilities. Bitbucket Pipelines stays in charge of orchestration — running your lint, tests, and tagging logic, and deciding _when_ a build should happen. When it's time to build iOS, a single [Capawesome CLI](/docs/cloud/cli/) call hands the job to [Capawesome Cloud](https://capawesome.io/), which runs it on Apple Silicon M4 runners with current Xcode versions.

Because the build runs in the cloud, your `bitbucket-pipelines.yml` never needs a macOS image. It runs on the standard `node:20` container, installs the CLI, and triggers the build. The cloud handles cloning your repo, running the web build and native sync (for Capacitor and Cordova apps), compiling with Xcode, and signing the result.

It's worth saying plainly: this is not Capacitor-only. Capawesome Cloud builds **native iOS projects written in Swift or Objective-C** just as happily as it builds Capacitor or Cordova apps — the build type and signing flow are the same regardless of framework.

## One-Time Setup[¶](#one-time-setup "Permanent link")

You only need to do this once per app.

First, create an app in Capawesome Cloud. You can do it from the [console](https://console.cloud.capawesome.io) or from your terminal:

`[](#%5F%5Fcodelineno-0-1)npx @capawesome/cli apps:create
`

Next, connect your Bitbucket repository. In the console, open your app's **Git** page, choose **Bitbucket** as the provider, authorize access, and select the repository you want to build. This lets the cloud check out your code by Git reference.

Then upload your iOS signing assets. iOS code signing needs two things — a distribution certificate as a `.p12` file (which bundles the certificate and its private key) and a `.mobileprovision` provisioning profile. Upload them once on the app's **Certificates** page, give the certificate a name like `Production iOS`, and the cloud stores them as named, reusable objects. You reference them by name at build time instead of stuffing base64 blobs into CI variables. See the [iOS certificates guide](/docs/cloud/native-builds/certificates/) for the full walkthrough, including how to generate a `.p12` if you don't have one — or create the CSR and `.p12` signing certificate in your browser, without a Mac, using the free [iOS Certificate Generator](https://capawesome.io/tools/ios-certificate-generator/).

Finally, give your pipeline permission to talk to the cloud. Create a Capawesome Cloud API token, then add it as a [secured repository variable](https://support.atlassian.com/bitbucket-cloud/docs/variables-and-secrets/) in Bitbucket under **Repository settings → Repository variables**:

* Name: `CAPAWESOME_CLOUD_TOKEN`
* Value: your token
* Check **Secured** so it's masked in logs

The CLI reads this variable automatically — you don't pass the token on the command line.

## Build iOS from Bitbucket Pipelines[¶](#build-ios-from-bitbucket-pipelines "Permanent link")

With setup done, building iOS is one step. Here's a `bitbucket-pipelines.yml` that builds an App Store binary every time you push to `main`:

`[](#%5F%5Fcodelineno-1-1)image: node:20
[](#%5F%5Fcodelineno-1-2)
[](#%5F%5Fcodelineno-1-3)pipelines:
[](#%5F%5Fcodelineno-1-4)  branches:
[](#%5F%5Fcodelineno-1-5)    main:
[](#%5F%5Fcodelineno-1-6)      - step:
[](#%5F%5Fcodelineno-1-7)          name: Build iOS app
[](#%5F%5Fcodelineno-1-8)          script:
[](#%5F%5Fcodelineno-1-9)            - npm install -g @capawesome/cli@latest
[](#%5F%5Fcodelineno-1-10)            - npx @capawesome/cli apps:builds:create --app-id 00000000-0000-0000-0000-000000000000 --platform ios --type app-store --certificate "Production iOS" --git-ref $BITBUCKET_COMMIT
`

A few things worth pointing out. The image is plain `node:20` — no macOS runner anywhere in this file. `$BITBUCKET_COMMIT` is a [built-in Bitbucket variable](https://support.atlassian.com/bitbucket-cloud/docs/variables-and-secrets/), so the cloud builds the exact commit that triggered the pipeline. And `--certificate "Production iOS"` points at the signing assets you uploaded earlier, so the resulting `.ipa` comes out signed and ready.

The `--type` flag controls what kind of build you get. For iOS the supported values are `simulator`, `development`, `ad-hoc`, `app-store`, and `enterprise` — pick the one that matches where the build is headed.

## Ship to TestFlight & the App Store[¶](#ship-to-testflight-the-app-store "Permanent link")

Building is half the job. To get the binary in front of testers, add a **destination**. A destination holds your App Store Connect credentials and tells the cloud where to deliver a build.

Create one once with your App Store Connect API key:

`[](#%5F%5Fcodelineno-2-1)npx @capawesome/cli apps:destinations:create --app-id 00000000-0000-0000-0000-000000000000 --name "TestFlight" --platform ios
`

The command will prompt for the details it needs — your Apple Team ID, Issuer ID, and the API key file. With the destination in place, you can build and deploy in a single pipeline step by adding `--destination`:

`[](#%5F%5Fcodelineno-3-1)image: node:20
[](#%5F%5Fcodelineno-3-2)
[](#%5F%5Fcodelineno-3-3)pipelines:
[](#%5F%5Fcodelineno-3-4)  branches:
[](#%5F%5Fcodelineno-3-5)    main:
[](#%5F%5Fcodelineno-3-6)      - step:
[](#%5F%5Fcodelineno-3-7)          name: Build & deploy iOS to TestFlight
[](#%5F%5Fcodelineno-3-8)          script:
[](#%5F%5Fcodelineno-3-9)            - npm install -g @capawesome/cli@latest
[](#%5F%5Fcodelineno-3-10)            - npx @capawesome/cli apps:builds:create --app-id 00000000-0000-0000-0000-000000000000 --platform ios --type app-store --certificate "Production iOS" --destination "TestFlight" --git-ref $BITBUCKET_COMMIT
`

Now a push to `main` produces a signed build and uploads it to TestFlight without you opening Xcode. If you'd rather decouple the two — build on every push, but deploy only when you decide — you can promote an existing build to a destination on its own:

`[](#%5F%5Fcodelineno-4-1)npx @capawesome/cli apps:deployments:create --app-id 00000000-0000-0000-0000-000000000000 --build-number 42 --destination "TestFlight"
`

## Internal Builds & On-Device Testing[¶](#internal-builds-on-device-testing "Permanent link")

Not every build is for the App Store. For QA and stakeholder review, an `ad-hoc` or `development` build is faster — and Capawesome Cloud gives every build a QR code for over-the-air installs. A tester scans it and the app lands on their device in under a minute, with no review queue in the way.

A common pattern is a separate, manually triggered pipeline for internal builds. Bitbucket's [custom pipelines](https://support.atlassian.com/bitbucket-cloud/docs/pipeline-triggers/) let you run a step on demand from the Bitbucket UI:

`[](#%5F%5Fcodelineno-5-1)image: node:20
[](#%5F%5Fcodelineno-5-2)
[](#%5F%5Fcodelineno-5-3)pipelines:
[](#%5F%5Fcodelineno-5-4)  custom:
[](#%5F%5Fcodelineno-5-5)    internal-ios-build:
[](#%5F%5Fcodelineno-5-6)      - step:
[](#%5F%5Fcodelineno-5-7)          name: Build ad-hoc iOS app
[](#%5F%5Fcodelineno-5-8)          script:
[](#%5F%5Fcodelineno-5-9)            - npm install -g @capawesome/cli@latest
[](#%5F%5Fcodelineno-5-10)            - npx @capawesome/cli apps:builds:create --app-id 00000000-0000-0000-0000-000000000000 --platform ios --type ad-hoc --certificate "Production iOS" --git-ref $BITBUCKET_COMMIT
`

Run it whenever a stakeholder asks for "the latest," share the QR code, and skip the App Store round trip entirely.

## Why This Beats a Self-Hosted Mac[¶](#why-this-beats-a-self-hosted-mac "Permanent link")

Once it's running, the difference from babysitting a Mac mini is hard to overstate:

* **No hardware to maintain.** No machine to patch, no Keychain to unlock, no runner that drops offline overnight.
* **Xcode stays current.** New Xcode versions are typically available within days of Apple's release, so you're not blocked when a new iOS requires the latest SDK.
* **Signing is managed, not hacked.** Certificates and provisioning profiles are named objects you upload once — not base64 blobs juggled through CI variables.
* **Builds are quick.** Apple Silicon M4 runners turn most iOS builds around in a few minutes.

Your team keeps pushing to Bitbucket exactly as they do today. The iOS build just stops being the part of the pipeline that nobody wants to own.

## FAQ[¶](#faq "Permanent link")

### Can Bitbucket Pipelines build iOS apps at all without Capawesome Cloud?[¶](#can-bitbucket-pipelines-build-ios-apps-at-all-without-capawesome-cloud "Permanent link")

Only if you bring your own macOS machine. Atlassian's hosted runners are Linux containers, and Bitbucket has no hosted macOS image, so `xcodebuild` has nowhere to run unless you register a self-hosted runner on a Mac you own and maintain. That's the gap this guide closes — the `bitbucket-pipelines.yml` itself never needs a macOS image, because the actual build is [handed off to Capawesome Cloud's own Apple Silicon runners](https://capawesome.io/solutions/build-without-mac/).

### Does this only work for Capacitor apps?[¶](#does-this-only-work-for-capacitor-apps "Permanent link")

No. Capawesome Cloud builds native iOS projects written in Swift or Objective-C the same way it builds Capacitor or Cordova apps — the CLI call, signing flow, and destination setup are identical regardless of framework.

### What's the difference between `apps:builds:create` and `apps:deployments:create`?[¶](#whats-the-difference-between-appsbuildscreate-and-appsdeploymentscreate "Permanent link")

`apps:builds:create` compiles and signs the app; adding `--destination` to that same command also uploads it to TestFlight or the App Store in one step. [apps:deployments:create](/docs/cloud/cli/commands/#appsdeploymentscreate) is for decoupling the two — it takes a build that already exists (referenced by `--build-number`) and promotes it to a destination separately, which is useful if you want every push to `main` to produce a build, but only want to deploy specific builds after manual approval.

### Do I need a different setup for internal QA builds versus App Store releases?[¶](#do-i-need-a-different-setup-for-internal-qa-builds-versus-app-store-releases "Permanent link")

Not a different setup, just a different `--type` value and typically a separate pipeline trigger. `ad-hoc` and `development` builds skip the App Store destination entirely and instead give you a QR code for direct over-the-air installs — see [How to Distribute iOS and Android Apps to Testers](/blog/how-to-distribute-ios-and-android-apps-to-testers/) for the full internal-testing workflow — so a common pattern is a manually triggered custom pipeline (as shown in this guide) for internal builds, alongside the automatic `main`\-branch pipeline for App Store submissions.

### Where do I store my signing certificate so it's not sitting in Bitbucket variables?[¶](#where-do-i-store-my-signing-certificate-so-its-not-sitting-in-bitbucket-variables "Permanent link")

Upload the `.p12` certificate and `.mobileprovision` profile once on the app's **Certificates** page in the Capawesome Cloud console, give the certificate a name, and reference it by name (`--certificate "Production iOS"`) in your pipeline. This avoids base64-encoding signing assets into Bitbucket repository variables, which is the more common — and riskier — approach with a fully self-managed setup.

## Related Posts[¶](#related-posts "Permanent link")

* [Build and Deploy iOS Apps with GitLab CI/CD](/blog/build-and-deploy-ios-apps-with-gitlab-ci-cd/)
* [Announcing Capawesome Cloud Native Builds](/blog/announcing-capawesome-cloud-native-builds/)
* [Announcing Capawesome Cloud Web Builds](/blog/announcing-capawesome-cloud-web-builds/)
* [How to Build a Cordova iOS App Without a Mac](/blog/build-cordova-ios-app-without-a-mac/)

## Get Started[¶](#get-started "Permanent link")

You can wire up your first cloud-built iOS pipeline today — no Mac, no credit card.

[Try Capawesome Cloud Free](https://capawesome.io)

## Conclusion[¶](#conclusion "Permanent link")

Bitbucket Pipelines doesn't do iOS on its own, but it doesn't have to. By keeping Bitbucket as your orchestrator and handing the macOS build off to [Capawesome Cloud](https://capawesome.io/) with a single CLI call, you get signed builds and TestFlight deployments from the pipeline your team already uses — without owning or maintaining a Mac. Whether you're shipping a native Swift app, a Capacitor app, or a Cordova app, the workflow is the same.

If you're curious how a specialized platform compares to wiring everything up yourself, our post on [why CI/CD specialization wins](/blog/ci-cd-for-capacitor-apps/) digs into the trade-offs. Got questions about your own setup? Join the [Capawesome Discord server](https://discord.gg/VCXxSVjefW), and subscribe to the [Capawesome newsletter](https://capawesome.io/newsletter/) to catch new guides as they ship.

July 17, 2026 

Back to top

```json
{
      "@context": "https://schema.org",
      "@type": "BlogPosting",
      "headline": "Build \u0026 Ship iOS Apps with Bitbucket Pipelines",
      "description": "Bitbucket Pipelines has no hosted macOS runners. Here\u0027s how to build, sign, and ship iOS apps from your Bitbucket pipeline using Capawesome Cloud and its CLI.",
      "image": "https://capawesome.io/assets/banners/cloud-build-and-deploy-capacitor-apps.png",
      "datePublished": "2026-06-02T00:00:00+00:00",
      "dateModified": "2026-07-17T00:00:00+00:00",
      "author": [
        {
          "@type": "Person",
          "name": "Robin Genz",
          "url": "https://github.com/robingenz"
        }
      ],
      "publisher": {
        "@type": "Organization",
        "name": "Capawesome",
        "url": "https://capawesome.io",
        "logo": {
          "@type": "ImageObject",
          "url": "https://capawesome.io/assets/images/logo.svg"
        }
      },
      "articleSection": "Cloud",
      "keywords": ["Cloud", "Guides"],
      "isPartOf": {
        "@type": "Blog",
        "@id": "https://capawesome.io/blog/#blog"
      },
      "mainEntityOfPage": "https://capawesome.io/blog/build-and-deploy-ios-apps-with-bitbucket/",
      "url": "https://capawesome.io/blog/build-and-deploy-ios-apps-with-bitbucket/"
    }
{
      "@context": "https://schema.org",
      "@type": "BreadcrumbList",
      "itemListElement": [
        {
          "@type": "ListItem",
          "position": 1,
          "name": "Home",
          "item": "https://capawesome.io/"
        },
        {
          "@type": "ListItem",
          "position": 2,
          "name": "Blog",
          "item": "https://capawesome.io/blog/"
        },
        {
          "@type": "ListItem",
          "position": 3,
          "name": "Build \u0026 Ship iOS Apps with Bitbucket Pipelines",
          "item": "https://capawesome.io/blog/build-and-deploy-ios-apps-with-bitbucket/"
        }
      ]
    }
{"@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [{"@type": "Question", "name": "Can Bitbucket Pipelines build iOS apps at all without Capawesome Cloud?", "acceptedAnswer": {"@type": "Answer", "text": "Only if you bring your own macOS machine. Atlassian's hosted runners are Linux containers, and Bitbucket has no hosted macOS image, so xcodebuild has nowhere to run unless you register a self-hosted runner on a Mac you own and maintain. That's the gap this guide closes — the bitbucket-pipelines.yml itself never needs a macOS image, because the actual build is handed off to Capawesome Cloud's own Apple Silicon runners."}}, {"@type": "Question", "name": "Does this only work for Capacitor apps?", "acceptedAnswer": {"@type": "Answer", "text": "No. Capawesome Cloud builds native iOS projects written in Swift or Objective-C the same way it builds Capacitor or Cordova apps — the CLI call, signing flow, and destination setup are identical regardless of framework."}}, {"@type": "Question", "name": "What's the difference between apps:builds:create and apps:deployments:create?", "acceptedAnswer": {"@type": "Answer", "text": "apps:builds:create compiles and signs the app; adding --destination to that same command also uploads it to TestFlight or the App Store in one step. apps:deployments:create is for decoupling the two — it takes a build that already exists (referenced by --build-number) and promotes it to a destination separately, which is useful if you want every push to main to produce a build, but only want to deploy specific builds after manual approval."}}, {"@type": "Question", "name": "Do I need a different setup for internal QA builds versus App Store releases?", "acceptedAnswer": {"@type": "Answer", "text": "Not a different setup, just a different --type value and typically a separate pipeline trigger. ad-hoc and development builds skip the App Store destination entirely and instead give you a QR code for direct over-the-air installs — see How to Distribute iOS and Android Apps to Testers for the full internal-testing workflow — so a common pattern is a manually triggered custom pipeline (as shown in this guide) for internal builds, alongside the automatic main -branch pipeline for App Store submissions."}}, {"@type": "Question", "name": "Where do I store my signing certificate so it's not sitting in Bitbucket variables?", "acceptedAnswer": {"@type": "Answer", "text": "Upload the.p12 certificate and.mobileprovision profile once on the app's Certificates page in the Capawesome Cloud console, give the certificate a name, and reference it by name ( --certificate \"Production iOS\") in your pipeline. This avoids base64-encoding signing assets into Bitbucket repository variables, which is the more common — and riskier — approach with a fully self-managed setup."}}], "url": "https://capawesome.io/blog/build-and-deploy-ios-apps-with-bitbucket/"}
```
