GitHubの自作ライブラリを公開する(CI導入編)

Swiftの自作ライブラリ(Kanagata)をGitHubに公開するにあたってのメモ。 その1ではCIの導入周りについての内容

なお、作成するフレームワーク名、プロジェクト名はKanagataとした場合の手順なので、 他の作業時は適宜読み替えること

その2はこちら

構成

せっかくなので単なるライブラリの公開だけでなく、以下の感じでそれっぽく公開

CIの導入

プロジェクトの作成

今回は既存のプロジェクトの中で使っていたものをフレームワークとして切り出す為、まずは新規プロジェクトを作成

作成時には、

をつけて作成する。 既存のソースとテストの各ファイルを移植したら、.hのファイルを削除 (Swiftのみなのでヘッダは不要)

ちなみに、ここで一旦ビルドとテストを実行するとmodule file's minimum deployment target is ios10.1のエラー。。。 その時のDeployment TargetはiOS9で問題ないはず。が、iOS10へ変更したりクリーンをしたりしても変わらず。 最後にダメ元でiOS9のシミュレータをDLしてみると、無事完了。 他の環境で試すと再現しなかったりで、結局原因はよく判らなかった・・・・

さて、無事?テストも通ったのでGitHubへpushしておく

TravisCI

CIツールにTravisCIを選択したのは、GitHubと連携できてiOSのビルドができてタダなので

登録

  1. トップページからSign in with GitHubのボタンを押して、GitHubとの連携を許可
  2. しばらくすると、GitHubのリポジトリの一覧が表示される
    (表示されない時は再ログインしてみればOK)
  3. 今回のプロジェクトを選んで有効化

プロジェクトの修正

登録が終わればXcodeのSchemeの設定を変更する

この時のスキーム名はCIの設定で使うので覚えておくこと!

設定

リポジトリの直下に.travis.ymlを追加し、CIで行う作業を設定する

この書き方がよく判らなかったので、いろいろなライブラリのリポジトリを見て 試した結果たどり着いた書き方(テストを実行するだけの最低限)がこちら

language: objective-c  # Swiftだけどobjective-cを指定
osx_image: xcode8.1    # 使っているXcodeのバージョン
script:
  # テストを実行(schemeにスキーム名を指定する)
  - xcodebuild test -scheme Kanagata -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 5'
notifications:
  email: false         # メール通知はOFF

変更が終わればスキームと.travis.ymlの変更分をpushする。
その後はpushする毎に自動でCIが走るようになる (だいたい、pushしてから15分程度で開始されることが多い感じ)

カバレッジ表示

TravisCISwiftに対応していてバッジが表示できてタダのものということで、 Codecovを選択
開発時はXcode内でカバレッジを見るのでどういう詳細表示がされるのかは重視していない

登録と設定

こちらもTravisCIと同じくGitHubとの連携だけで登録完了

便利なのが、リポジトリを選択するとTravisCIに設定するコードを表示してくれること。
表示されたコードを.travis.ymlに追加すればOK

ignoreの設定

デフォルトの状態ではリポジトリ内全部が対象となるので、テスト用のコードもカウントされてしまい、 正しくないカバレッジが表示されてしまう。それを防ぐため、テスト用のコードは対象外とする様に設定する

リポジトリ直下にcodecov.ymlを追加し、以下を追記する

ignore:
  - "KanagataTests"

これでKanagataTests以下のフォルダは対象外となる

SwiftLint

SwiftLintにはAuto-correctというコードフォーマッタの機能があり、 これを使いたいので導入した

インストール

なぜかSierraではHomebrewでインストールできなかったので、パッケージからインストール

Xcodeに設定

Auto-correctはビルド時に毎回走らせたいので、Xcode上でのビルド設定に追加する

  1. フレームワーク用のターゲットのBulid Phasesを開く
  2. New Run Script Phaseで以下のスクリプトを追加

    if which swiftlint >/dev/null; then
    swiftlint autocorrect
    swiftlint
    else
    echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint"
    fi
    
  3. 追加したRun ScriptCompile Sourcesより上に移動

これでビルドを試してみて、たくさんエラーとワーニングが出ればOK

ルールのカスタマイズ

デフォルトの状態ではかなり厳しい設定で、エラーやワーニングが出まくるので調整する

リポジトリ直下に.swiftlint.ymlを追加し、無視するルールや変更する基準値を書いていく

調整内容は各プロジェクトにもよるが、今回は以下の感じに調整した

included:
  - Kanagata
variable_name:
  min_length: 0
line_length:
  - 120
  - 150
type_body_length:
  - 350
  - 400
function_body_length:
  - 50
  - 100
cyclomatic_complexity: 25
disabled_rules:
  - nesting
  - file_length

具体的には1ファイルに詰め込んだ都合上、行数制限をゆるめに設定。 また、JSONの構造上、再起処理や型ごとの処理で複雑性が増しているのでそこもゆるめにした

CIに設定

CIの時にはチェックだけされる様に設定を.travis.ymlに追加

before_install:
  - brew update
  - brew install swiftlint
script:
  - swiftlint   # xcodebuild testより前にしておく

(今回追加した分のみ記載)

CI環境にはSwiftLintが入っていないので実行前にインストールが必要。 なお、Homebrewではなく、パッケージからインストールさせるとCIにかかる時間が減るらしい

バッジを貼る

TravisCI

リポジトリのビルド結果の画面の中に表示されているバッジをクリックすると、 貼り付ける用のURLが出てくるので、*マークダウン*形式をコピーしてREADMEに貼り付け

Codecov

リポジトリの画面の中のSettings - Badgeで貼り付ける用のURLが出てくるので、 こちらも*マークダウン*形式をコピーしてREADMEに貼り付け

ドキュメント生成

基本publicになるものにはドキュメントコメントをつけていて、juzzyでドキュメント生成をしていたが、 CocoaPodsに公開すればCocoaDocsが出来上がるので不要に。。。

一旦、まとめ

ここまでの手順で、pushすると

  1. SwiftLintで静的解析
  2. XCTestでユニットテスト
  3. ユニットテストのカバレッジを送信

といったところまで自動で実行される状態となる

参考リンク