Fastlaneを使用してアプリのビルド・リリースパイプラインを作成〜Flutter〜
2025-04-08
azblob://2025/04/08/eyecatch/2025-04-08-azurepipeline-app-000.png

はじめに


入社して1年、アルバイト期間を含めると2年弱が経ちました。

新卒が新たに入社し、私も先輩になったというわけです。そんなこともあり、新卒研修の時にめちゃくちゃやばかったのを思い出しました。

そもそもGithubとは何か、コードに関して何もわからないのに入社しました。動く爆弾ですね〜

デモ動作確認では何がいい感じか知りませんけど、コミットにおーい!って書いてましたこわ

そんな私ですが、リリース作業を何度もやり、リリースにかかる時間が長すぎて嫌になってしまっていました。

なので、パイプラインを作成し、自動化しました。

パイプラインで実現したかった内容


自由時間の確保

ビルド→リリースストア公開まで

ビルドバージョンは手動で変え、コミットを打った瞬間にパイプラインが発火

(pubspec.ymlの内容に変更があった場合にパイプラインを動かすってのはできるけど結局やらず終わりました。)

パイプラインを作成する際に面倒くさかったこと


既存のものでは権限が足りなかったため、iOS Distribution 証明書をパイプライン用で用意しないといけなかったこと

証明書の解凍のためにパスワードが必要なのに忘れて困ったこと(自分のミス)

(権限に応じてできることとできないことがあるので、証明書周りはちゃんと管理しないとですね)

流用する人はいないと思うので、自分が思い出せる程度に書いておきます。

trigger


mainにマージされたタイミングで発火させたいですが、リリース時にはいろんな兼ね合いがあることが多いので、noneにしています。

pool


Macを指定しています。iOSアプリなので、Macで作業を行うからです。

variable group


環境変数をLibraryのvariable groupに追加しているので引っ張っています。

BuildAndDistribute


Flutterのインストールを必ず行う。これやらないと一生ビルドできないです。以下のコード流用で動かせます。

P12_XXX


証明書のパスワード、Libraryのvariable group内に追加しているのでこれでOK

KEYCHAIN_PASSWORDは、macOS のキーチェーンにアクセスするために必要なパスワードを格納している変数

ymlファイルの構成



trigger:none 

pool:
  vmImage: 'macos-latest'

variables:
- group: NATIVE_APP_RELEASE_DEV  # 変数グループを指定

jobs:
- job: BuildAndDistribute
  steps:
  - script: |
      echo "Flutterのインストールを確認しています"
      if ! [ -x "$(command -v flutter)" ]; then
        echo "Flutterがインストールされていません。Flutterをインストールしています..."
        git clone https://github.com/flutter/flutter.git  -b stable
        export PATH="$PATH:$(pwd)/flutter/bin"
        flutter doctor
      else
        echo "Flutterはすでにインストールされています。"
        flutter --version
      fi
    displayName: 'Flutterの確認とインストール'
  
  - script: |
      echo "Flutterの依存関係を取得しています"
      export PATH="$PATH:$(pwd)/flutter/bin"
      flutter pub get
    displayName: 'Flutterの依存関係を取得'

  - task: DownloadSecureFile@1
    name: downloadProvisioningProfile
    inputs:
      secureFile: 'Pipeline.mobileprovision'
    displayName: 'Download provisioning profile'

  - task: InstallAppleProvisioningProfile@1
    inputs:
      provisioningProfileLocation: 'secureFiles'
      provProfileSecureFile: ‘任意のファイル名’
    displayName: 'Install provisioning profile'

  - task: DownloadSecureFile@1
    name: downloadCertificate
    inputs:
      secureFile: ’任意の.p12ファイル名’
    displayName: 'Download certificate'

  - script: |
      echo "証明書をインストールしています..."
      security import "$(Agent.TempDirectory)/XXX.p12" -P $(P12_XXX) -T /usr/bin/codesign
      security set-key-partition-list -S apple-tool:,apple: -s -k $(KEYCHAIN_PASSWORD) ~/Library/Keychains/login.keychain-db
    displayName: 'Install Certificate'

  - script: |
      echo "IPAファイルを生成しています..."
      flutter build ipa --export-method ad-hoc --flavor= dev --obfuscate --split-debug-info=symbol/
    displayName: 'Flutterアプリのビルド'

  - script: |
      if [ "$(distributionType)" = "internal" ]; then
        echo "内部テスター用に配布します"
        bundle exec fastlane distribute_internal
      else
        echo "外部テスター用に配布します"
        bundle exec fastlane distribute_external
      fi
    displayName: 'TestFlightへの配布'

FastFileの構成


default_platform(:ios)
platform :ios do
 desc "Build and distribute to TestFlight for internal testers"
 lane :distribute_internal do
   match(type: "adhocプロビジョニングプロファイルを使用") 
   build_app(
     scheme: "任意のスキーム名",
     export_method: "ad-hoc" 
   )
   upload_to_testflight(
     beta: true, # 内部テストの指定
     team_id: "任意のチームID" 
   )
 end
 desc "Build and distribute to TestFlight for external testers"
 lane :distribute_external do
   match(type: "appstore") # App Store プロビジョニングプロファイルを使用
   build_app(
     scheme: "任意のスキーム名",
     export_method: "app-store" # App Store エクスポートメソッドを使用
   )
   upload_to_testflight(
     beta: false, # 外部テストの指定
     team_id: "任意のチームID" 
   )
 end
end

Matchfile


プロビジョニングファイルの設定の追加もここにしておくといいですね。

git_url("https://github.com/GitリポジトリのURL.git ") 
git_branch("main") # 使用するブランチ

# 証明書の種類
type("adhoc") # "adhoc" または "appstore" を指定

終わりに


勉強勉強の毎日ですがこれからも頑張っていきたいです。