CI
を中心としたワークフローやリリース(デプロイ)自動化システムを構築するには、現在対象としているコードベースの状態を把握する必要があります
- ブランチは、feature か master か
- プルリクエストをマージしたのか
- タグはついているのか
Travis CI
でそれらを把握するためには表題にある 3 つの環境変数の意味と組み合わせを理解しないと出来ないのですが、まとまった公式のドキュメントやネット上のレファレンスが見つからなかったので書きます
http://aniszczyk.org/2012/04/05/travis-ci/ より
Travis CI を使ったリリース自動化の例
例えば、最近試した iOS のプロジェクトでは、次のような、Travis CI を使った比較的複雑な、ワークフローの構築とリリース自動化を行いました
- なぜこうしているのかという意図などは、リンク先の README にある程度詳細に書いているのでご参照ください
feature ブランチを master ブランチに対してプルリクエストした場合
-
テスト
する -
ビルドしてバイナリを生成
する - そのバイナリをチームメンバーがインストールできるホスティングサービスに
デプロイ
する
feature ブランチを master ブランチにマージした場合
- プルリクエストした場合とやることは同じ
- ただし、
デプロイ先アドレスは変える
(= マスターブランチから生成したバイナリとフィーチャーブランチから生成したバイナリは分けてホスティングする)
タグをつけたコミットをプッシュした場合
-
テスト、ビルド、ホスティングサービスにデプロイ
までは同じ(マージの時と同じようにデプロイ先アドレスは変える) - 次に、
GitHub Releases に生成したバイナリをデプロイ
する - さらに、このレポジトリに依存したレポジトリのリリース作業も行っていく
- 依存レポジトリの
appledoc 更新、バージョン番号の更新、コミット、マスターにプッシュ
する - 依存レポジトリの
GitHub Pages を更新
する - 依存レポジトリを
GitHub Releases に公開
する
状態を把握するために、.travis.yml で参照できる 3 つの環境変数
上記に書いたような、場合分けを伴うリリース自動化をするために参照する環境変数は次の 3 つです(これらの環境変数は、Travis CI 側で値を設定しているものです)
TRAVIS_PULL_REQUEST
TRAVIS_BRANCH
TRAVIS_TAG
TRAVIS_PULL_REQUEST
型
- 文字列
取りうる値
- false
- プルリクエストではない場合
- 1 など
- プルリクエストである場合
- プルリクエスト番号が入る
TRAVIS_BRANCH
型
- 文字列
取りうる値
- master や feature1 など
- タグのプッシュではない場合
- ブランチ名が入る
- v1.0.0 など
- タグのプッシュである場合
- タグ名が入る
TRAVIS_TAG
型
- 文字列
取りうる値
- 空白
- タグコミット(= タグプッシュ)ではない場合
- v1.0.0 など
- タグコミット(= タグプッシュ)である場合
-
git tag
でつけたタグ名が入る
Git / GitHub 上での操作を例に、3 つの環境変数の組み合わせをまとめる
- GitHub 上で Travis CI と連携している前提です
- 運用フロー(≒ ワークフロー)は、GitHub Flow を採用している前提です
- ただし、iOS などネイティブアプリを念頭に置いているので、master をすぐにリリースするわけではなく、リリースはタグをつけて別に行うという点は注意ください
- 仮に、feature ブランチ名を
created-readme
とする - 仮に、プルリクエスト番号を
8
とする - 仮に、タグ名を
v10.0.13
とする
feature ブランチをプッシュした
-
git push origin created-readme
などした場合に実行されます -
continuous-integration/travis-ci/push
と表示されているのはこれです - https://travis-ci.org/yoheimuta/mtburn-ios-sdk-demoapp/builds/52122672#L170
TRAVIS_PULL_REQUEST | TRAVIS_BRANCH | TRAVIS_TAG |
---|---|---|
"false" | "created-readme" | "" |
feature ブランチのプルリクエストを master ブランチに出した
- GitHub 上で p-r ボタンを押したりした場合に実行されます
-
continuous-integration/travis-ci/pr
と表示されているのこれです - https://travis-ci.org/yoheimuta/mtburn-ios-sdk-demoapp/builds/52122736#L175
TRAVIS_PULL_REQUEST | TRAVIS_BRANCH | TRAVIS_TAG |
---|---|---|
"8" | "master" | "" |
feature ブランチを master ブランチにマージした
- GitHub 上の p-r ページでマージボタンを押したときに実行されます
- https://travis-ci.org/yoheimuta/mtburn-ios-sdk-demoapp/builds/53778003#L174
TRAVIS_PULL_REQUEST | TRAVIS_BRANCH | TRAVIS_TAG |
---|---|---|
"false" | "master" | "" |
タグをプッシュした
-
git tag -a v10.0.13 -m"version up" && git push --tags origin master
などした場合に実行されます - https://travis-ci.org/yoheimuta/mtburn-ios-sdk-demoapp/builds/52851779#L187
TRAVIS_PULL_REQUEST | TRAVIS_BRANCH | TRAVIS_TAG |
---|---|---|
"false" | "v10.0.13" | "v10.0.13" |
注意点
- feature ブランチのプルリクエストを master ブランチに出したときに、
TRAVIS_PULL_REQUEST
が8
でTRAVIS_BRANCH
がcreated-readme
でも実行されるのかなと思ったのですが、されません
最後に
参考になるかもしれない、蛇足を書きます
タグをプッシュするときの例
make release NEXT_VERSION=1.0.1
- ファイル中のいくつかのバージョン番号を置換して、タグをつけてプッシュします
- https://github.com/yoheimuta/mtburn-ios-sdk-demoapp/blob/master/Makefile から抜粋
release:
if [ -z "$(NEXT_VERSION)" ] ; then exit 1; fi
$(eval CURRENT_VERSION := $(shell echo $$(git for-each-ref --sort=-taggerdate --format="%(tag)" refs/tags | head -n 1 | sed -e "s/v//")))
git checkout master
sed -i '' -e"s/$(CURRENT_VERSION)/$(NEXT_VERSION)/g" \
DemoApp/DemoApp-Info.plist
git add .
git commit -m"Updated version to v$(NEXT_VERSION)"
git tag -a v$(NEXT_VERSION) -m"Updated version to v$(NEXT_VERSION)"
git push --tags origin master
.travis.yml にて、環境変数を使った例
- やっていることは、
Travis CI を使ったリリース自動化の例
にあるとおりです - 補足する点があるとすれば、
before_deploy -> deploy -> after_deploy
までを実行するかどうかの判定は、Travis CI 側でTRAVIS_TAG
が空でないかどうかで勝手に行ってくれています - http://docs.travis-ci.com/user/deployment/releases/ に仕様が書いてあります
- https://github.com/yoheimuta/mtburn-ios-sdk-demoapp/blob/master/.travis.yml から抜粋
before_script:
- '[ "$TRAVIS_BRANCH" == "master" ] && [ "$TRAVIS_PULL_REQUEST" != "false" ] && MTB_PR=1 || echo "This is master or not PR"'
- '[ "$TRAVIS_BRANCH" == "master" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ] && MTB_MERGE_MASTER=1 || echo "This is not master or PR"'
- 'DEPLOYGATE_MESSAGE=$(git rev-parse --short HEAD)'
- '[ "$MTB_PR" ] && DEPLOYGATE_MESSAGE+=#"$TRAVIS_PULL_REQUEST" || echo "Not append PR number"'
- echo TRAVIS_BRANCH=${TRAVIS_BRANCH}
- echo TRAVIS_PULL_REQUEST=${TRAVIS_PULL_REQUEST}
- echo TRAVIS_TAG=${TRAVIS_TAG}
- echo MTB_PR=${MTB_PR}
- echo MTB_MERGE_MASTER=${MTB_MERGE_MASTER}
- echo DEPLOYGATE_MESSAGE=${DEPLOYGATE_MESSAGE}
script:
- make test
- '[ "$MTB_PR" ] && make append-pr-to-bundleid || echo "Not append -pr to bundleid"'
- '[ "$MTB_MERGE_MASTER" ] && make append-master-to-bundleid || echo "Not append -master to bundleid"'
- '( [ "$MTB_PR" ] || [ "$MTB_MERGE_MASTER" ] || [ "$TRAVIS_TAG" ] ) && make ipa || echo "Skip to make ipa"'
- '( [ "$MTB_PR" ] || [ "$MTB_MERGE_MASTER" ] || [ "$TRAVIS_TAG" ] ) && make deploygate DEPLOYGATE_MESSAGE="$DEPLOYGATE_MESSAGE" || echo "Skip to make deploygate"'
after_success:
- make send-coverage
before_deploy:
- 'NEXT_VERSION=$(echo ${TRAVIS_TAG} | sed -e "s/v//")'
- echo NEXT_VERSION=${NEXT_VERSION}
- make release-public-repo NEXT_VERSION=$NEXT_VERSION
deploy:
provider: releases
api_key:
secure: gvj2V09zMPsHDPhNoQCpP4ouMUqq7mdq7g2l79dRSTOqGh/diJpgRWKCOZdZ5hYibpe0ynDckixS3ZLyPGhsvx7qfCxNcWDpdmtZtSSv7yuoc3PEbV56QtFfaoCCJacHWohKjRd2+hymDs6bxfPQ3WjnaMAbA48CdEY3QQEftpg=
file: DemoApp.ipa
skip_cleanup: true
on:
repo: yoheimuta/mtburn-ios-sdk-demoapp
tags: true
all_branches: true # https://github.com/travis-ci/travis-ci/issues/1675
after_deploy:
- gem install dpl
- make deploy-public-repo
iOS のリリース自動化に関連して、cocoapods ライブラリのリリースについて
https://github.com/yoheimuta/mtburn-ios-sdk-demoapp#only-manual-operation-to-be-required に書いたのですが、2015/03/07 まではできませんでしたが、COCOAPODS_TRUNK_TOKEN
という環境変数を使うことで、Travis CI などの CI を使ったリリースが出来るようになりました
- 手元で出来ることは確認しました
- 以前、自分がやろうとしたときに出来ないことを確認するのはけっこう大変だったので、メモ書き程度ですがひとこと書きました(最近追加されたので、出来ないままだと思っている人もいるかもしれないので)
Travis CI に関連して、Caching Ubuntu packages に http://packages.treasuredata.com
が加わってます
2015/02/09 まで、cache apt:true
を追加すると、sudo curl -L http://toolbelt.treasuredata.com/sh/install-ubuntu-precise-td-agent2.sh | sh
が失敗していたと思います
- travis が管理している cached APT repositories に http://packages.treasuredata.com が含まれていなかったためです
-
http://docs.travis-ci.com/user/caching/#Caching-Ubuntu-packages にメールしてくれと書いてあるのでメールしたら追加してくれたので、今は
cache apt:true
しても失敗しません(docs の url リストにはなぜかまだ追加されていないですが) - 前に 1 回やろうとしてこれを理由に apt キャッシュを見送った経緯もあるので(そのときの担当は自分でないので予想ですけど)、共有する場所もないので、メモ書き程度ですがひとこと書きました