launchctlで定期的にMonoTouch製Appをリリースビルドするには

MonoTouchのリリースビルドはコンソールから以下のコマンドで可能。

/Applications/MonoDevelop.app/Contents/MacOS/mdtool build ソリューションファイル名 -c:'コンフィグ名'

コンフィグ名とは'Ad-Hoc|iPhone'や'Release|iPhone'のこと。

上記をふまえるとビルド用シェルスクリプトは以下のようになる。

#/bin/sh

ulimit -n 1024
security unlock-keychain -p パスワード /Users/myuser/Library/Keychains/login.keychain
/Applications/MonoDevelop.app/Contents/MacOS/mdtool build ソリューションファイル名 -c:'コンフィグ名'

mdtoolはAppへ署名するためにキーチェインにアクセスしようとする。GUIの場合はアクセス許可の旨のダイアログが表示されるが、コンソールからアクセスするときはアクセスが拒否されてエラーで終わってしまう。なのでmdtoolの前にsecurityコマンドでキーチェーンをアンロックする必要がある。
ulimitはmdtoolが1プロセスで大量のファイルをオープンすることがあるので制限を解除する必要がある。

次にビルド用シェルスクリプトをlaunchctlに登録する。
以下のようなplistファイルを/Library/LaunchDaemons/に作成する。
ここでplistファイルのパーミッションは644。オーナーはrootにする必要がある。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>com.myapp.autobuild</string>
  <key>ProgramArguments</key>
  <array>
    <string>起動するコマンドへのフルパス(シェルスクリプト)</string>
  </array>
  <key>StartCalendarInterval</key>
  <dict>
    <key>Minute</key>
    <integer>00</integer>
  </dict>
  <key>RunAtLoad</key>
  <false/>
  <key>ExitTimeout</key>
  <integer>600</integer>
  <key>UserName</key>
  <string>myuser</string>
  <key>GroupName</key>
  <string>staff</string>
  <key>OnDemand</key>
  <true/>
  <key>SessionCreate</key>
  <true/>
</dict>
</plist>

LabelとProgramArgumentsはlaunchctlの仕様上必ず必要だが、MonoTouchをビルドするために必要なものとしてさらにUserName、GroupName、SessionCreateが必要になる。

UserName、GroupNameはMonoTouchのライセンスファイルへのアクセスに必要となる。
MonoTouchはライセンスファイルがユーザー毎に登録されている。この値を省略した場合はmdtoolがライセンスファイルにアクセスできず正しくビルドできない。よってMonoTouchをアクティベートしたユーザーを明示的に指定しなければならない。

SessionCreateはキーチェーンにアクセスの為に必要となる。
シェルスクリプト内のsecurityコマンドでアンロックをしているがこれだけでは足りない模様。SessionCreateを明示的にtrueにすることでアクセスできるようになる。


追記 2013/03/21 10:25
ulimitを追加した。