メインコンテンツにジャンプ

Bitbucket Pipelinesを使用したiOSアプリのビルドとデプロイ

iOSアプリをビルド、署名、テストフライトに送信する方法

iOSアプリをビットバケット Pipelines でビルドおよびデプロイする

Bitbucket Pipelines は、ホストされた Mac のランナー上で iOS アプリをビルドすることはできません。なぜなら、Xcode は Linux コンテナ上で実行されるステップすべてで実行されるからです。Mac を自社の Bitbucket ランナーとして登録するか、Linux ステップを維持し、iOS コンパイル、署名、テストフライト アップロードをクラウド ビルド サービスに任せることができます。このガイドでは両方の方法を示し、完全なファイルを __CAPGO_KEEP_0__ アプリに含めています。 bitbucket-pipelines.yml チームがすでに Bitbucket で Capacitor のレビュー、Jira のリンク、デプロイを実行している場合、iOS 用に 2 番目の CI ツールが必要ありません。Pipeline は Bitbucket 内に残ります。Mac を必要とする部分だけが移動します。

If your team already lives in Bitbucket for code review, Jira links, and deployments, you do not need a second CI tool just for iOS. The pipeline stays in Bitbucket. Only the part that needs a Mac moves.

iOS ビルドが Bitbucket Pipelines で失敗する理由

Bitbucket Pipelinesは、選択したDockerイメージの中で各ステップを実行します ("node:22, cimg/androidAtlassianのLinuxインフラストラクチャ上で実行されるため、問題ありません。 bun installiOSアプリのビルドとデプロイは、Bitbucket Pipelinesで実行できます。

  • xcodebuild, codesign、MacOS上のみiOS SDKが存在します。
  • Apple製品のライセンスはmacOSをApple製品以外のハードウェアで実行することを許可していないため、署名されたiOSアプリを生成するLinuxイメージは存在しない。 .ipa.
  • Since April 28, 2026, App Store Connect rejects uploads that were not built with Xcode 26 and the iOS 26 SDK, so whatever Mac you use has to stay current. See AppleのXcode 26の要件は、Capacitorアプリに適用されます。.

ビットバケットは、Linux、Windows、macOSで自社のランナーをサポートしています。アトラシアンは、自社のランナーで実行されるステップのビルド時間に対して料金を請求しませんが、ハードウェアとメンテナンスのコストは負担します。

あなたの3つの選択肢

オプション iOS ビルドが実行される場所 MacOSを使用したiOSアプリのビルドとデプロイ 適切な選択
自社のMacOSランナー Mac miniまたはレンタルしたMac MacOS、Xcode、キーチェーン、証明書、ディスクスペース、稼働時間 既にMacを所有し、誰かがそれらを実行できるチーム
2番目のCIはモバイル用 別のベンダーのMac 2つのpipeline、2つのシークレット、トリガー モバイルCIを専用で望むチーム
Cloud BuildはLinuxステップから呼び出される Capgo BuildのMacファーム 1 つの CLI コールと数少ないセキュアな変数 Capacitor チームがビットバケットを CI のみのプラットフォームとして残したい

このガイドの残りの部分では、1 番目と 3 番目のオプションについて詳細に説明します。iOS アプリのプラットフォームについてのより広い視点を知りたい場合は、 iOS アプリの CI/CD プラットフォームの比較.

Linux ステップから iOS をビルドするオプション 1: Capgo ビルド

Capgo ビルド compiles and signs Capacitor apps on Capgo-managed Macs. Your Bitbucket step does what it already does well on Linux: install dependencies, build the web layer, and run cap sync ios.Capgo CLIは、準備されたネイティブプロジェクト(あなたのウェブソースcodeや__)をアップロードします。 node_modulesを実行します。次に、__CAPGO_KEEP_0__ __CAPGO_KEEP_1__ は準備されたネイティブ プロジェクト (ウェブ ソース __CAPGO_KEEP_2__ または

Because your runner pushes the project to Capgo, Capgo never needs access to your Bitbucket repository. There is no repository connection to authorize and no OAuth app to approve.

Prerequisites

  • A Capacitor app that builds locally (Capacitor 8 needs Node.js 22 or newer)
  • Apple Developer Program のメンバーシップにチーム管理者権限
  • Capgo アカウントと API キー(アップロード許可)
  • Capgo に登録されたアプリ bunx @capgo/cli@latest app add

マシン上の 1 回限りの設定

マシン上で 1 回のオンボーディングを実行します。iOS では、または再利用するためにディストリビューション証明書とプロビジョニング プロファイルを作成し、App Store Connect の API キーを要求します。

bunx @capgo/cli@latest login
bunx @capgo/cli@latest build init --platform ios

__CAPGO_KEEP_0__ iOS 証明書生成ツールを使用して、ブラウザで証明書署名要求を作成することもできます。 Windows で __CAPGO_KEEP_0__ ビルドを使用して iOS アプリをビルドします。、またはフォロー Bitbucket から Capgo をエクスポートします。.

__CAPGO_KEEP_0__ はマシン上に資格情報を保持します。資格情報を Bitbucket に移動するには、dotenv ファイルにエクスポートします。

bun run build
bunx cap sync ios
bunx @capgo/cli@latest build request com.example.app --platform ios --build-mode release

__CAPGO_KEEP_0__

CLIは、機器上のクレデンシャルを保持します。Bitbucketに移すには、dotenvファイルにエクスポートします。

bunx @capgo/cli@latest build credentials manage --appId com.example.app --platform ios
# choose "Export to .env" in the menu

この書き込み .env.capgo.com.example.app.ios モードで 0600. 以下のキーが含まれます:

変数 コンテンツ
BUILD_CERTIFICATE_BASE64 あなたの配布用証明書のBase64 .p12 証明書のパスワード (なければ空白)
P12_PASSWORD __CAPGO_KEEP_0__によって生成されたプロビジョニングプロファイルマッピング
CAPGO_IOS_PROVISIONING_MAP_BASE64 App Store Connect CLIキーID
APPLE_KEY_ID App Store Connect API ID
APPLE_ISSUER_ID Base64の
APPLE_KEY_CONTENT アプリ .p8 APIキー
APP_STORE_CONNECT_TEAM_ID Apple チーム ID

各行を追加してください セキュア Bitbucket の "リポジトリ設定 > Pipelines > リポジトリ変数" に追加してください , さらに, plus CAPGO_TOKEN CapgoのCapgo APIキーを使用してください。セキュアな変数はログにマスクされ、UIから読み取ることができません。

If you prefer the API, this loop creates them in one go. It uses a Bitbucket API token with the pipeline variables write scope.

WORKSPACE=my-team
REPO=my-app
ENV_FILE=.env.capgo.com.example.app.ios

grep -v '^#' "$ENV_FILE" | grep '=' | while IFS= read -r line; do
  key="${line%%=*}"
  value="${line#*=}"
  value="${value%\"}"; value="${value#\"}"
  jq -n --arg k "$key" --arg v "$value" '{key:$k, value:$v, secured:true}' |
    curl -s -u "$BB_EMAIL:$BB_API_TOKEN" \
      -H 'Content-Type: application/json' \
      -X POST --data @- \
      "https://api.bitbucket.org/2.0/repositories/$WORKSPACE/$REPO/pipelines_config/variables" > /dev/null
  echo "created $key"
done

rm "$ENV_FILE"

に追加してください .env.capgo.* to .gitignoreに追加してください

プロダクション用クレデンシャルについては、 デプロイ変数を考慮する リポジトリ変数の代わりに Productionデプロイ変数はデプロイ環境にスコープがついています(例えば、)、そしてプレミアムプランでは管理者や特定のブランチに制限できます。

パイプラインファイル

Bitbucketはリポジトリとデプロイ変数を環境変数としてインジェクトするので、Capgo CLIはマッピングなしで取得できます。このファイルは、プッシュごとにテストを実行し、オンデマンドでアドホックiOSビルドを作成し、バージョンタグでTestFlightに配信します:

# bitbucket-pipelines.yml
image: node:22

definitions:
  caches:
    bun: ~/.bun/install/cache

pipelines:
  default:
    - step:
        name: Lint and test
        caches:
          - bun
        script:
          - curl -fsSL https://bun.sh/install | bash
          - export PATH="$HOME/.bun/bin:$PATH"
          - bun install --frozen-lockfile
          - bun run lint
          - bun run test

  tags:
    'v*':
      - step:
          name: Build iOS and upload to TestFlight
          deployment: Production
          caches:
            - bun
          script:
            - curl -fsSL https://bun.sh/install | bash
            - export PATH="$HOME/.bun/bin:$PATH"
            - bun install --frozen-lockfile
            - bun run build
            - bunx cap sync ios
            - >
              bunx @capgo/cli@latest build request com.example.app
              --platform ios
              --build-mode release
              --ios-distribution app_store

  custom:
    ios-adhoc:
      - step:
          name: Ad hoc iOS build for testers
          caches:
            - bun
          script:
            - curl -fsSL https://bun.sh/install | bash
            - export PATH="$HOME/.bun/bin:$PATH"
            - bun install --frozen-lockfile
            - bun run build
            - bunx cap sync ios
            - echo "$ADHOC_PROFILE_BASE64" | base64 --decode > adhoc.mobileprovision
            - >
              bunx @capgo/cli@latest build request com.example.app
              --platform ios
              --build-mode release
              --ios-distribution ad_hoc
              --ios-provisioning-profile ./adhoc.mobileprovision
              --output-upload
              --output-retention 2d
              --output-record /tmp/build.json
            - bunx @capgo/cli@latest build last-output --path /tmp/build.json --field outputUrl

いくつかの重要な点があります:

  • イメージは単純なLinux node:22. macOSが必要なものは何もありません。
  • Linuxでは cap sync ios ウェブアセットをコピーし、ネイティブ設定を更新しますが、CocoaPodsを実行することはできません。問題ありません。ビルドを実行するMacがPodsをインストールまたはSwiftパッケージを解決します。
  • CapgoはApp Store Connectから最新のビルド番号を読み取り、インクリメントするので、”バンドルバージョンは以前アップロードしたバージョンよりも高くなければなりません”というエラーに遭遇することはありません。 --skip-build-number-bump 自分で管理する場合。
  • アドホックビルドには、アドホックプロビジョニングプロファイルが必要です。これは、リストされているデバイスにのみインストールされます。セキュアな変数として保存してください。 ADHOC_PROFILE_BASE64 フラグは、環境からアプリストアプロファイルを上書きします。このビルドのみに適用されます。テスターのUDIDsをiOS UDID finderで収集してください。 --ios-provisioning-profile iOS UDID finder バージョンを固定するために__CAPGO_KEEP_0__をピン留めしてください (例えば).
  • パイプラインが安定したら、CLIのリリースはスプリント中の動作を変更できません。 @capgo/cli@7.104.0) パイプラインが安定したら、CLI リリースはミドルスプリント中の動作を変更できません。

パイプライン > パイプライン実行 > ios-adhoc 最後のコマンドは、保持期間が経過すると期限切れになるダウンロードリンクを出力します。テストフライトへの手動承認

Bitbucketは

サポートしています trigger: manual iOSアプリをビルドしてBitbucket Pipelinesでデプロイする

  tags:
    'v*':
      - step:
          name: Test
          script:
            - curl -fsSL https://bun.sh/install | bash
            - export PATH="$HOME/.bun/bin:$PATH"
            - bun install --frozen-lockfile
            - bun run test
      - step:
          name: Ship iOS to TestFlight
          trigger: manual
          deployment: Production
          script:
            - curl -fsSL https://bun.sh/install | bash
            - export PATH="$HOME/.bun/bin:$PATH"
            - bun install --frozen-lockfile
            - bun run build
            - bunx cap sync ios
            - bunx @capgo/cli@latest build request com.example.app --platform ios --build-mode release

TestFlightのアップロードに人間が承認する場合、リリースをビルドステップとゲート付きアップロードステップに分割することができます: --submit-to-store-review with --store-release-name "$BITBUCKET_TAG"with

App Store Connectでアプリのリスト表示、スクリーンショット、コンプライアンス回答が完了している必要があります。

Android builds can run directly on Bitbucket’s Linux runners, but you can also send them to Capgo Build so both platforms use the same signing and upload flow. Use a parallel block:

  tags:
    'v*':
      - parallel:
          - step:
              name: iOS release
              script:
                - curl -fsSL https://bun.sh/install | bash
                - export PATH="$HOME/.bun/bin:$PATH"
                - bun install --frozen-lockfile && bun run build
                - bunx cap sync ios
                - bunx @capgo/cli@latest build request com.example.app --platform ios --build-mode release
          - step:
              name: Android release
              script:
                - curl -fsSL https://bun.sh/install | bash
                - export PATH="$HOME/.bun/bin:$PATH"
                - bun install --frozen-lockfile && bun run build
                - bunx cap sync android
                - bunx @capgo/cli@latest build request com.example.app --platform android --build-mode release --android-track internal

ブロックを使用します: ANDROID_KEYSTORE_FILE, KEYSTORE_KEY_ALIAS, KEYSTORE_KEY_PASSWORD, KEYSTORE_STORE_PASSWORDAndroidステップには PLAY_CONFIG_JSON 、 --platform android.

セキュアな変数としてエクスポートする必要があります。

Most commits to a Capacitor app only touch HTML, CSS, and JavaScript. Those do not need a new binary. With Capgo ライブアップデート, Bitbucket ステップはストアビルドとオーバー・ザ・エアバンドルのどちらかを決定します:

  branches:
    main:
      - step:
          name: Release (live update or native)
          script:
            - curl -fsSL https://bun.sh/install | bash
            - export PATH="$HOME/.bun/bin:$PATH"
            - bun install --frozen-lockfile
            - bun run build
            - |
              if bunx @capgo/cli@latest build needed com.example.app --channel production; then
                echo "No native change, shipping a live update"
                bunx @capgo/cli@latest bundle upload com.example.app --channel production
              else
                echo "Native change detected, building iOS"
                bunx cap sync ios
                bunx @capgo/cli@latest build request com.example.app --platform ios --build-mode release
              fi

build needed code 0 が必要な場合に 0、1 の場合に 1 になります。ネイティブ プラグインのバージョンをチェックし、チャンネル上で実行中のものと比較します。マニュアル編集は見えません。 ios/__CAPGO_KEEP_0__ 自動で live update またはネイティブビルドを選択.

オプション 2: macOSランナーを自宅でホスト

ランナーを登録する

Bitbucket にアクセスし、

  1. リポジトリ設定 > ランナー (または (or context Bitbucket Pipelinesを使用してiOSアプリをビルドおよびデプロイする 実行者を追加.
  2. 選択 MacOS システムとしてMacOSを選択します。Bitbucketは実行者UUIDとOAuth認証情報を含む起動コマンドを表示します。
  3. Mac上で、サポートされているJDK (実行者はJavaプログラム) をインストールし、Xcode 26、およびfastlaneをインストールします。次に、起動コマンドをペーストします。
  4. 実行者を再起動後に生き残るように、Mac上で実行者を実行してください。

ステップはラベルで実行者をターゲットにします。

pipelines:
  tags:
    'v*':
      - step:
          name: iOS build on our Mac
          runs-on:
            - self.hosted
            - macos
          script:
            - bun install --frozen-lockfile
            - bun run build
            - bunx cap sync ios
            - echo "$BUILD_CERTIFICATE_BASE64" | base64 --decode > dist.p12
            - echo "$PROFILE_BASE64" | base64 --decode > profile.mobileprovision
            - bundle exec fastlane ios beta

macOS実行者は、ホスト上でユーザーの環境を使用して直接実行され、コンテナ内では実行されません。Mac自体にBunとRubyをインストールしてください。

最小限のFastfile

default_platform(:ios)

platform :ios do
  lane :beta do
    setup_ci(force: true)

    api_key = app_store_connect_api_key(
      key_id: ENV["APPLE_KEY_ID"],
      issuer_id: ENV["APPLE_ISSUER_ID"],
      key_content: ENV["APPLE_KEY_CONTENT"],
      is_key_content_base64: true
    )

    import_certificate(
      certificate_path: "dist.p12",
      certificate_password: ENV["P12_PASSWORD"],
      keychain_name: "fastlane_tmp_keychain",
      keychain_password: ""
    )
    install_provisioning_profile(path: "profile.mobileprovision")

    update_code_signing_settings(
      path: "ios/App/App.xcodeproj",
      use_automatic_signing: false,
      team_id: ENV["APP_STORE_CONNECT_TEAM_ID"],
      code_sign_identity: "Apple Distribution",
      profile_name: ENV["PROFILE_NAME"]
    )

    increment_build_number(
      xcodeproj: "ios/App/App.xcodeproj",
      build_number: latest_testflight_build_number(api_key: api_key) + 1
    )

    build_app(
      project: "ios/App/App.xcodeproj", # use workspace: "ios/App/App.xcworkspace" for CocoaPods projects
      scheme: "App",
      export_method: "app-store"
    )

    upload_to_testflight(api_key: api_key, skip_waiting_for_build_processing: true)
  end
end

新しいCapacitor 8プロジェクトは、Swift Package Managerを使用しているため、ビルド App.xcodeproj古いプロジェクトはまだCocoaPodsを使用しているため、ビルド App.xcworkspace と必要 pod install ランナー上で GitHub Actions iOS ガイド 各fastlaneアクションの詳細は、Bitbucket上のレーンは同じです。

サインアップするもの

アーカイブは簡単な部分です。自宅でMacをホストする場合:

  • Xcodeのアップグレード アップルが最小限のSDKを引き上げたとき
  • キーチェーンの状態。 ジョブがクラッシュすると、間欠的なキーチェーンが残り、次のジョブは間違ったアイデンティティを取得します。
  • 隔離なし。 ジョブは同じディスク上で実行されます。DerivedData、古いアーカイブ、シミュレータがディスクを埋め尽くします。
  • 一つのビルドごとに 各ランナーあたり、Macを追加購入しない限り。
  • サーバーサイド証明書とプロファイル 毎年有効期限切れのものは、機器上で毎年更新する必要があります。

Macをすでに管理しているチームの場合、そこまでのコストは妥当です。誰もそのボックスを所有したくない場合は、オプション1で削除します。

Troubleshooting

症状 可能性と解決策
CAPGO_TOKEN is not set 変数が欠落している、またはステップにはキーが存在しない。 deployment: ステップは
タグでは機能しません main ステップは機能します デプロイメント変数は、デプロイメント環境を宣言するステップのみに適用されます。
Provisioning profile doesn't match bundle ID 別のアプリIDのプロファイルが作成されました。再実行して再エクスポートしてください。 build init アンド
アプリストア接続の認証に失敗しました。 App Store Connect のキーを確認してください。キー ID または発行者 ID が正しくありません、またはキーが取り消されました。 App Store Connect > ユーザーとアクセス > 統合を確認してください。
バージョン SDK のアップロードが拒否されました。 Xcode 26 より前のバージョンを使用したビルドです。自宅 Mac をアップグレードしてください。
自宅 Mac のステップが「保留中」に固定されています。 ランナーがオフラインまたはラベルが一致しません。 self.hosted アンド macos.
errSecInternalComponent コード署名中 非対話セッションで鍵チェーンがロックされています。 setup_ci と、臨時キーチェーンに証明書をインポートします。
ビルドは成功しますが、テストフライトには何も表示されません。 処理には数分かかり、エクスポートの準備が完了していない可能性があります。追加 ITSAppUsesNonExemptEncryption を Info.plist あなたのアプリが標準暗号化のみを使用している場合。

context Fixing build failures in Capacitor CI/CD pipelines とともに Capgo iOSアプリのビルドトラブルシューティングガイド.

どのオプションを選択するべきですか?

Pick a self-hosted Mac when you already own the hardware, need full control of the Xcode environment, or build native Swift targets that are not Capacitor apps. Pick a cloud build from a Linux step when your app is a Capacitor app and you want Bitbucket to stay the single place your team configures CI. Either way, keep the build logic in bitbucket-pipelines.yml Capgoの隣に、codeの横に署名材料を安全な変数に格納し、ネイティブcodeが実際に変更された場合のみネイティブビルドを実行する。

Live updates for Capacitor apps

When a web-layer bug is live, ship the fix through Capgo instead of waiting days for app store approval. Users get the update in the background while native changes stay in the normal review path.

Capgoから最新のブログ記事

Capgoは、プロフェッショナルなモバイルアプリを作成するために必要な最良の洞察を提供します。