トレタ開発者ブログ

飲食店向け予約/顧客台帳サービス「トレタ」、モバイルオーダー「トレタO/X」などを運営するトレタの開発メンバーによるブログです。

リリース自動化だけじゃないfastlane活用方法

この記事はトレタ Advent Calendar 2016 1日目の記事になります。

こんにちは、昨日に引き続き開発部の堀見です。

今年はトレタ初のエンジニアアドベントカレンダーをやることになりました!
「トレタ Advent Calendar 2016」やります - トレタ開発者ブログ

弊社はまだまだ小さい組織で少人数なので、言い出した当初は「半分埋まれば良いか〜」とか言っていましたが、なんと・・・全日程埋まっています!!!!🎉🎉🎉

弊社のデザイナー・サーバサイド・インフラ・フロント・iOSのエンジニアが勢揃いしてますので、ぜひトレタ Advent Calendar 2016 の購読ボタンを押してウォッチしてください🙏

ということで、初日は筆者からiOSネタを投下します。

背景

最近多くのiOS開発現場ではfastlaneでリリース作業が自動化されていると思います。トレタでも去年からfastlaneを導入済みで、ブランチをmasterにマージするとCIでアーカイブ作成・iTunesConnectにバイナリをアップできるようになっています。これによりリリース作業の負担軽減や、作業の属人性が減らせました。

しかし、日々のiOS開発ではまだまだ作業効率化の余地があると思います。今回は筆者がよく非エンジニア等のチームメンバーから依頼される、ちょっとした作業をfastlaneを使って自動化してみました。おそらくiOSエンジニアであればお願いされた経験があるものが多いと思います。

Provisioning ProfileにUDIDを追加する

弊社ではベータ版アプリを社員にはIn-house、社外の協力会社様向けにはAd-Hocビルドで配布しています。そのため社外でテストしたい端末が増えると、都度UDIDをDeveloper Portalに追加するという作業が発生します。

一瞬で終わる作業ですが、大抵ログインセッションが切れていてポータルに再ログイン、ポータルTOPからDevice追加画面に進み(ページ遷移が多い!)、デバイス名とUDIDを入力してようやく終了。・・・と思いきや、provisioningにデバイスIDを追加しないと意味がありません。というか、これをよく忘れてビルドをアップし、インストールできませんと言われて気づくことが割とあります...。意外と時間がかかってしまう作業です。

そこで以下のようなlaneを用意し、コマンド一発でデバイス追加とprovisioningの更新を行えるようにしました。

desc 'Usage: fastlane add_device name:デバイス名 udid:デバイスのUDID'
lane :add_device do |options|
  if options[:name] && options[:udid]
    register_devices(devices: {options[:name]: options[:udid]})
    sigh(force: true)
  else
    UI.error "Usage: fastlane add_device name:'New device name' udid:'UDID'"
  end
end

ブラウザをポチポチ操作していれば数分はかかりますが、これなら10秒程度で終わります。デバイス追加をお願いする際は、name:デバイス名 udid:デバイスのUDIDの形式で送ってもらうようお願いしておけば、依頼が来て即ターミナルにコピペ・コマンドを叩いて終了です。

ベータ配布済みのアプリのProvisioningを新しいものに差し替えたい

ベータ版配布サービスで既に配布しているAd-Hocアプリに、利用できるユーザを追加したいというケースもよくあります。前述のデバイス追加とProvisioningの更新をやっていれば新しいビルドをアップするだけで解決するんですが、長いビルド時間を待つのは億劫だし、同じビルド番号のアプリが配布サイト上に重複していくのも嫌な感じです。なので、普段は既にアップしているipaを手元にダウンロードして、Provisioningを入れ替え、アップし直すという地味な作業をやっています。

これもfastlaneからコマンド一発で行えるようにしました。

まずベータ配布サービスからアップ済みのipaをダウンロードしてきます。弊社ではHockeyAppを使っているので、download_hockey_ipaというActionを作りました。ビルド番号などを指定したらAPI経由でipaをダウンロードしてくるシンプルなものですが、地味に行数が長いので詳しくはGistで。

download_hockey_ipa.rb

ダウンロードが完了したらsighで最新のProvisioningをダウンロードし、resignでipaの中身を差し替え、再度hockeyでipaをアップします。幸いダウンロード以降はfastlaneに含まれているアクションを組み合わせて完結しました。

desc 'Usage: fastlane update_hockey_ipa_profile build_number:1234'
lane :update_hockey_ipa_profile do |options|

  tmp_download_path = '/tmp/resign.ipa'
    
  download_hockey_ipa(
    api_token: ENV["FL_HOCKEY_API_TOKEN"],
    build_number: options[:build_number],
    public_identifier: 'Hockeyアプリのidentifier',
    ipa_path: tmp_download_path
  )

  sigh(username: "dev@example.com", development: true, app_identifier: "*")
  resign(signing_identity: ENV["DEVELOPMENT_SIGNING"], ipa: tmp_download_path)
    
  hockey(ipa: tmp_download_path, strategy: 'replace')
end

hockeyアクションはデフォルトだと新規のビルドとしてipaをアップしますが、strategy:'replace'オプションを加えておくとHockey上にある同じ番号のビルドを置き換えてくれるようです。

最新のLocalizationを適用した確認用アプリを用意する

弊社のアプリは英語圏にもサービス展開しており、通常の機能開発と並行してローカライズも行っています。言語リソースはCrowdinで管理していて、翻訳が完了したらxliff形式で訳語データをダウンロード、コードにimportするという流れです。

これもまたブラウザからファイルを取ってきてimportして...とやっていると地味に時間がかかるので、コマンド一発で解決します。

まずはCrowdinから言語リソースをダウンロードしてきます。OneSkyなどはfastlane-plugin-oneskyを使えば済むようですが、Crowdinは無かったので自前でActionを用意。こちらも長いのでGistを参照↓

download_crowdin_resource.rb

続いてCrowdinからダウンロードしたxliffをプロジェクトにインポートします。xcodebuildコマンドをシェルで叩いてもいいんですが、fastlane-plugin-localizationを使うと簡潔に書けそうなのでこちらを使います。

最終的なlaneはこんな感じ。import処理はprivate laneに書いて、betaビルドのlaneから必要に応じて呼び出し、Hockeyにバイナリアップするようにしています。

private lane :update_localization do |options|
  tmp_localization_path = '/tmp/localization.xliff'
  download_crowdin_resource(
    api_token: ENV["CROWDIN_API_TOKEN"],
    download_path: tmp_localization_path,
    project_identifier: 'toreta',
    language: options[:language],
    file_to_download: 'ipad.xliff'
  )
  import_localizations(source_path: tmp_localization_path, project: 'Toreta.xcodeproj')
end

desc 'Usage: fastlane beta update_localization:true language:en'
lane :beta do |options|
    
  if options[:update_localization]
    update_localization(language: options[:language])
  end
    
  sigh(username: "dev@example.com", app_identifier: "*")
  gym
  hockey
end

まとめ

fastlaneを使って日々の作業を地味に自動化する方法を紹介しました。 一つ一つは些細な作業ですが、意外と自分の時間が削られてしまうし、「後でいいや」と後回しにすればチームメンバーを待たせてしまいます。こうした小さな効率化もエンジニアの責務としてやるべきだなと思いました。

fastlaneはもはやリリース自動化ツールではなく、アプリエンジニアが日々こなすあらゆる仕事の量を軽減し、生産性を高めてくれるツールになっている印象です。fastlane/AvailablePluginsにもあるように有志で開発されたプラグインもどんどん充実してきているので、今後さらなる効率化が図れそうです。


明日は サーバサイドエンジニアの 芹沢PageRankについて調べてみたです。お楽しみに!

potatotips #35 を開催しました

開発部の堀見です。

昨日弊社でpotatotips #35 (iOS/Android開発Tips共有会)を主催させてもらいました!今回はそのレポートをお届けします🚀

発表内容

各発表の詳しいまとめについては、ブログまとめ枠で参加してくださった皆さんが内容を公開してくださっています↓(ブログが上がり次第、随時更新します)

Togetterもまとめて頂いています。ありがとうございます!

2016/11/29 #potatotips (iOS/Android開発Tips共有会) 第35回 - Togetterまとめ

こちらでも発表者の皆さんのスライドを紹介します。
(ハッシュタグ #potatotips でシェアされているスライドのみ載せています。まだアップしてない方も共有お待ちしております!)

1. トレタでのSwift 3 対応 by y_koh

2. MVVM で Protocol Oriented をやってみた話 by kumapo

3. iOSアプリ開発者なら簡単にできる!! TouchBarにツイートを表示するTips by y.imajo

4. Good Bye, Javascript Interface! by tomoima525

5. GitLab CI の布教 for iOS by ikamooon

6. FirebaseUI-Android by yamacraft

7. Embedded Framework in Action by TachibanaKaoru

8. Popoverを使うとiPhone/iPadの開発フローを簡単化できる by Yuta Hoshino

9. 一人で3アプリ同時並行して作ったら死にそうになった話 by Gazyu

10. Firebaseのススメ by nafu003

11. Android, iOS, Web開発を一人で回すコツ by koichi_adachi_7

12. UIコンポーネントを磨く by hayashi311

UIコンポーネントの作り方 #potatotips @トレタ - Qiita

13. Fabric Betaのオプションまとめ by horie1024


総勢13名の方が発表してくださいました。皆さんありがとうございました!

イベントの様子

機材不調で始まる前の会場が静寂に包まれるトラブルがありましたが😱無事開始しました。

f:id:horimislime:20161129203232j:plain

トップバッター、弊社iOSエンジニアのid:y_kohが発表中。

f:id:horimislime:20161129191950j:plain

会場から活発に質問が飛び交っていました。筆者も興味があるトピックが多かったので、司会をしつつ個人的に質問させてもらいました。
(途中、ネットワーク不調やUSB-Cアダプタの問題でお騒がせし申し訳ありませんでした🙇)

f:id:horimislime:20161129205650j:plain

LT後に弊社の事業について宣伝させてもらいました。これを機会にトレタに興味を持ってくれた方がいたら幸いです! 発表の中で紹介したブログや採用リンクはこちら。ぜひ見てみてください。

f:id:horimislime:20161129214403j:plain

最後にtry!Swift2017 TOKYOのお知らせ。今年も豪華なゲストを招いて開催するそうです。チケットを購入した人にはCFPへの応募権も!スポンサーも絶賛募集中とのことです。詳しくはtry! Swift TOKYOをチェック。

f:id:horimislime:20161129214933j:plain

懇親会

f:id:horimislime:20161129215950j:plain

弊社管理部のメンバーが厳選してくれた美味しいご飯を食べつつ、22時過ぎごろまで盛り上がりました。お越しいただいた皆さん、遅くまでお付き合い頂きありがとうございました!

弊社ではこれからもエンジニア向けイベントを開催していきたいと思うので、ぜひまたトレタへ遊びに来てください🙋

「トレタ Advent Calendar 2016」やります

こんにちは。ボケ防止に数学検定の問題集解くのが最近のマイブーム、サーバーサイドエンジニアの芹沢です。今年、数学検定2級を受験して2次試験不合格により見事に落としましたので来年リベンジします。

今年も残す所あと僅かとなり、みなさまに置かれましてはそろそろアドベントカレンダーの担当日の締め切りが気になり始める頃ではないでしょうか(自分は2015年は3つ参加してましたが日々いい感じにプレッシャーを感じながら師走を過ごした覚えがあります)。

今年はトレタもアドベントカレンダーにTryしてみることにしました。私も3日分参加する予定です。

f:id:serihiro:20161129141218p:plain

現在、弊社の開発部は総勢19名(エンジニア+デザイナー+プロジェクトマネージャー)ということで、総員でアドベントカレンダーに挑んでも1人辺り1.25記事書かないと埋まらない厳しい戦いを強いられております。
そのため、毎年のアドベントカレンダーを楽に25日分埋めてくれるエンジニア・デザイナーを広く募集しております。応募等の詳細はこちらからどうぞ。

© Toreta, Inc.

Powered by Hatena Blog