Concourse CIでiOSアプリのCIを行う


前にSIの現場のiOSアプリケーション開発 - Qiitaで書いたように、CIにはJenkinsを使っているのですが、特定メンバーがJenkins職人になりがちでツラみがあります。
せっかくfastlaneなどでビルドスクリプトをコード化出来ているので、ビルドパイプラインもコード化したい…!

ってことでConcourse CIを試してみました。

Concourse CIのインストール

docker-composeでやりました。
以下の公式ドキュメント通りに行えばサクッと起動します。

dockerでConcourse CIを構築して、iOSのビルド出来るのか?って心配になるかもしれませんが、Darwin用のworkerを利用することでiOSのビルドを行うことが可能です。

workerの設定

以下から最新のconcourse_darwin_amd64をダウンロードしてきて、パスの通ったディレクトリに配置します。
https://github.com/concourse/concourse/releases

worker用の鍵の生成とauthorized_worker_keysへの追加を行います。

$ ssh-keygen -t rsa -f ./keys/worker/darwin_worker_key -N ''
$ cat ./keys/worker/darwin_worker_key.pub >> ./keys/web/authorized_worker_keys

Macホスト上でconcourse workerを起動します。

$ sudo concourse worker --work-dir /opt/concourse/worker --tsa-host 127.0.0.1 --tsa-public-key ./keys/worker/tsa_host_key.pub --tsa-worker-private-key ./keys/worker/darwin_worker_key

とりあえずこれでworkerが動きました。

{"timestamp":"1487892702.682704926","source":"worker","message":"worker.garden.started","log_level":1,"data":{"session":"1"}}
{"timestamp":"1487892702.682797194","source":"baggageclaim","message":"baggageclaim.listening","log_level":1,"data":{"addr":"127.0.0.1:7788"}}
{"timestamp":"1487892702.683754444","source":"worker","message":"worker.beacon.restarting","log_level":2,"data":{"error":"failed to dial: failed to connect to TSA: dial tcp 127.0.0.1:2222: getsockopt: connection refused","session":"3"}}

2222番ポートで接続しようとしてエラーになっているので、docker-compose.ymlに設定を追加します。

docker-compose.yml
concourse-web:
  image: concourse/concourse
  links: [concourse-db]
  command: web
  ports: ["8080:8080", "2222:2222"]
  volumes: ["./keys/web:/concourse-keys"]
  environment:
    CONCOURSE_BASIC_AUTH_USERNAME: concourse
    CONCOURSE_BASIC_AUTH_PASSWORD: changeme
    CONCOURSE_EXTERNAL_URL: "${CONCOURSE_EXTERNAL_URL}"
    CONCOURSE_POSTGRES_DATA_SOURCE: |-
      postgres://concourse:changeme@concourse-db:5432/concourse?sslmode=disable

どうやら繋がったようです。

{"timestamp":"1487892892.915976048","source":"tsa","message":"tsa.connection.channel.forward-worker.register.start","log_level":1,"data":{"remote":"172.17.0.1:50078","session":"1.1.1.5","worker-address":"127.0.0.1:42459","worker-platform":"darwin","worker-tags":""}}
{"timestamp":"1487892892.928279877","source":"tsa","message":"tsa.connection.channel.forward-worker.register.reached-worker","log_level":0,"data":{"remote":"172.17.0.1:50078","session":"1.1.1.5","took":"10.962879ms"}}

ビルドパイプラインの作成

立ち上がっているWebにアクセスし、

ビルドパイプライン設定用のCLIツールであるflyをダウンロードします。

ダウンロードしたバイナリをパスが通っているディレクトリに配置しておきます。

とりあえず以下の3つを実行できるようにしてみます。

  • GitHubからclone
  • CocoaPodsで依存関係解決(fastlaneで)
  • fastlaneでテスト実行

最終的なyamlは以下の通りです。
ビルドの実行ユーザはrootになるのですが、pod installがrootで実行できないのでパーミッションだったりユーザのスイッチだったりごにょごにょやっています。

concourse.yml
resources:
  - name: ios-concourse
    type: git
    source:
      uri: https://github.com/tenten0213/ios-concourse.git
      branch: master
jobs:
  - name: build
    plan:
      - get: ios-concourse
        trigger: true
      - task: specs
        config:
          platform: darwin
          inputs:
            - name: ios-concourse
          run:
            path: sh
            args:
              - -c
              - |
                env
                mkdir ios-concourse/ExampleForConcourse/Pods
                chown -R $SUDO_USER ios-concourse/
                chown -R $SUDO_USER ~/Library/Caches/CocoaPods
                chown -R $SUDO_USER ~/.cocoapods
                cd ios-concourse/ExampleForConcourse
                sudo -u $SUDO_USER bundle exec fastlane test

パイプラインを登録して実行可能な状態にし、ビルドを実行すると…

$ fly -t ci login -c http://127.0.0.1:8080/
$ fly -t ci set-pipeline -p ios-concourse -c concourse.yml
$ fly -t ci unpause-pipeline -p ios-concourse

↓な感じでfastlaneが実行され、ビルドが成功しました!ヽ(=´▽`=)ノ
画像見れば分かる通り、ちゃんとビルド通すのに結構苦労しました…

試したモロモロは以下に置いてあります。

参考