🎭

AppStoreにリリースしたアプリのコードでもGithubに公開がしたい!(でも秘匿情報は隠したい)

2023/08/21に公開

想定の読者

App Storeに公開したアプリのコードをGitHubで管理&公開したいが、APIキーなどのProduction用の情報は隠したいと考えている方々

概要

任意のパブリックなリポジトリをサブモジュールとして参照するProduction用のプライベートリポジトリを作成します。XcodeCloudなどのCI/CD環境にも対応しており、Production用のworkspaceでコードの修正やstaging用のビルドが行えます。

この記事ではパブリックなStaging用リポジトリをStagingRepository,
プライベートなProduction用リポジトリをProductionRepositoryと呼びます。

サンプル

Stagingプロジェクトについて

以下のような様々なプロジェクト構造でも問題ありませんが、Xcodegenを使用した環境での確認は行っていません。

  • デフォルトのxcodeprojを使用した構成
  • Cocoapods, Carthageを使用した構成
  • SPMモジュールを使用した構成

ProductionRepositoryの作成とサブモジュールのセットアップ

ステップ1: Gitで管理される新しいフォルダを作成

$ mkdir ProductionRepository
$ cd ProductionRepository
$ git init

ステップ2: StagingRepositoryをサブモジュールとして追加

$ git submodule add git@github.com:your_username/StagingRepository.git

生成される.gitmodulesファイルをGitで管理します。
この時点でStagingRepositoryがクローンされ、.git/configが生成されます。
このStaging用プロジェクトのビルドができることを確認してください。

Production用のプロジェクトを作成

ステップ1: ProductionRepositoryに新しいxcodeprojworkspaceを作成

Staging用のxcodeprojworkspaceをコピーして、ProductionRepositoryに配置します。
もともとxcworkspaceを使用していない場合は、新たに作成します。XcodeのメニューからFile > New > Workspaceを選択して作成できます。
Staging.xcodeprojProduction.xcodeprojのようにそれぞれ改名するとわかりやすくなります。

ステップ2: xcworkspaceを編集

xcworkspaceの内部にcontents.xcworkspacedataという以下のようなXMLがあります。このファイルをテキストエディタで開き、Production.xcodeprojを参照するように修正します。

<?xml version="1.0" encoding="UTF-8"?>
<Workspace
   version = "1.0">
   <FileRef
      location = "group:StagingRepository/Pods/Pods.xcodeproj">
   </FileRef>
   <FileRef
      location = "group:Production.xcodeproj">
   </FileRef>
   <FileRef
      location = "group:StagingRepository/Staging.xcodeproj">
   </FileRef>
</Workspace>

ステップ3: ファイルパスを解決

Production.xcworkspaceを開くと見つからないファイルが赤く表示されているので、右側のインスペクタのフォルダマークからパスを解決します。

ステップ4: ビルドに必要な設定を調整

ビルドを試すと、Build Settingsで主に以下の項目でパスの不一致によるエラーが発生するのでそれぞれ解決します。

  • Code Sign Entitlements
  • Info.plist
  • Framework Search Path(importエラーが出た場合)
  • Development Assets(Production用では不要かもしれないが、無いとエラーが出る)
  • PODS_PODFILE_DIR_PATH ([CP] Check Pods Manifest.lockでエラーになる)
  • PODS_ROOT([CP] Check Pods Manifest.lockでエラーになる)

info.plistをProductionとStagingで出し分ける場合は新たなinfo.plistをProductionRepositoryに作成して設定します。

ステップ5: 不要なコンフィグレーションを削除

Production.xcodeprojではDebugコンフィグレーションは不要なので削除します。同様に、Staging.xcodeprojではReleaseコンフィグレーションを削除します。

ステップ6: ProductionRepositoryのxcworkspaceStagingビルドができるように設定

xcworkspaceを開いた状態で、staging.xcodeprojをドラッグ&ドロップしてインポートします。

ステップ7: これまでの変更をGitHubにプッシュ

最後に、これまでの変更をGitHubにプッシュします。

他メンバーの開発の流れ

  1. ProductionRepositoryをクローンし、サブモジュールをセットアップ。
  2. ProductionRepositoryのxcworkspaceを開いてコーディング。
  3. StagingRepository内の変更は、そのリポジトリに移動してコミット、プッシュ。
  4. ProductionRepositoryに移動して、StagingRepositoryの最新のコミットIDをコミットプッシュ。

XcodeCloudを使用する場合

  • Primary Project似ProductionRepositoryに設定し、workspaceもProductionRepositoryのものを使用。
  • ProductionRepository/ci_scripts/ci_post_clone.shに以下を記載。
#!/bin/bash

# Initialize the submodule
git submodule init

# Update the submodule
git submodule update

# Pod, Carthage等のセットアップ

参考資料

Swift PMとマルチプロジェクトでBuild Configurationをクリーンに保つ

Discussion