GAE/GoのWebアプリをCircleCIで自動テスト&自動デプロイするを見かけたので、OSSなら無料で使えるTravisCI版を書いておきます。
.travis.yml全体
※2015/01/28追記 GAE/GoでAppStoreのレビューをSlackに通知してくれるやつ作ったで紹介しているほうが少し新しくなっていますので、そちらも参照してください。
せっかちな人向けに先に設定結果を置いておきます。
こっちのリポジトリにも置いてあります。
https://github.com/yosukesuzuki/go-malt
language: go
before_install:
- pushd $HOME
- wget -q https://storage.googleapis.com/appengine-sdks/featured/go_appengine_sdk_linux_amd64-1.9.13.zip
- unzip -q go_appengine_sdk_linux_amd64-1.9.13.zip
- cd go_appengine
- export GAE=$(pwd)
- popd
- npm install -g grunt-cli
- git clone git://github.com/n1k0/casperjs.git ~/casperjs
- cd ~/casperjs
- git checkout tags/1.1-beta3
- export PATH=$PATH:`pwd`/bin
- cd -
install:
- cd $TRAVIS_BUILD_DIR
- export GOPATH=$TRAVIS_BUILD_DIR
- export GOHOME=$GAE
- export PATH=$GAE:$PATH
- which go
- go env
- go get github.com/gorilla/mux
- go get github.com/oleiade/reflections
- go get github.com/russross/blackfriday
before_script:
- goapp serve &
- sleep 5
script:
- goapp test;casperjs --pre=caspertests/helpers/adminlogin.coffee test caspertests/tests
after_success:
- python $GAE/appcfg.py update . --oauth2_refresh_token=$GAE_OAUTH -A dev-goappstarter
after_script:
- casperjs test tests --env=gaedev --user_id=$GAE_TEST_USER --user_password=$GAE_TEST_USER_PASSWORD
env:
global:
- secure: KiEdocf9yqxGaBaMO+5YwfrHWKEMIkqSZx40uOenLCJWvQbm+KRlvTjqyGR/SxJDqjYwS82LAdMILqhzVSjdhPgyJSSzMXXL/YkKccedkZJabHu6FXXwlkSRyxIyr1JRqeSzzSQHtYb8VqtKQ8GwqBeWcS9mZtT5Fhxx+WcH6QQ=
- secure: nksf9ORgB4yMnjf9qHbH0IfGgj9J4Nsk1bwArTMLDyxSDIduEg7p80HXPqD0K9KTrfshs8HqouYDz8T5z9wORn8sKLA/2c9I/CXl5H1Rh5CZY3V8Ai4jo2VDudvrtM8pfKoOFB3psWJVxAAfAp6PMYcVZ8uYb07HrK18CFL5Pvs=
- secure: IJvZ47LmYAxck5iqWaz7xhIt9Adj/Zq+jN/W86n+a5Fi7XRs6ZHSif1ZRrCacOT272//gHieG3ItCWS44i8e8bo1l/H9Vkp71juRinLD4fOE9LLboV4xtKfX7GOJcTM1vQTp0eKoZsvT6eRY7kSvEBZ84+tdkj2xnNYNFfQMMM8=
TravisとGithubリポジトリを連携させる
そもそもの設定。TravisCIにGithubアカウントでログインして、右上のプルダウンメニューからaccountsを選択すると自分の管理しているリポジトリの一覧が表示されます。デフォルトでは連携がOFFなので、ONにします。
refresh_tokenを用意する
CircleCI版のほうに説明があるので、そちらを参照してください。
refresh_tokenを暗号化する
open sourceとはいえ、誰でも本番環境にデプロイできてしまうと困りますよね。
そのために、TravisCIには暗号化という手段が用意されています。
詳しくはTravisのドキュメントを参照してください。
travisのコマンドラインツールをインストールします。
$ gem install travis
refresh_tokenの値を暗号化
$ travis encrypt GAE_OAUTH=hogehogehoge
これを実行すると.travisに暗号化されたキーが.travis.ymlに追加されます。
また、今回、appengineのadmin権限で実行するテストのためにGAE_TEST_USER、GAE_TEST_USER_PASSWORDという値も暗号化しています。
テスト環境を設定する
before_installのセクションの解説です。
GAE/Go SDKのダウンロード
wget(curlでも)でSDKを取得してダウンロードして、unzipします。
ちなみにGAEのSDKはマイナーバージョンの1つ前ぐらいしか、取得できなくなるので、久しぶりにテストを通そうとするとここがだいたい落ちます。自動的にlatestバージョンを追っかけてくれる方法ないかな?
※追記(2015.02.26)ありました、新しい別記事で言及しているのでそちらを参照してください。
- pushd $HOME
- wget -q https://storage.googleapis.com/appengine-sdks/featured/go_appengine_sdk_linux_amd64-1.9.13.zip
- unzip -q go_appengine_sdk_linux_amd64-1.9.13.zip
- cd go_appengine
- export GAE=$(pwd)
- popd
CasperJSのインストール
今回の題材にしているアプリのテストは、goのテストは少ししかありません。うまく、かけませんでした。その代わりに、CasperJSでのE2Eテストを書いてます。
- npm install -g grunt-cli
- git clone git://github.com/n1k0/casperjs.git ~/casperjs
- cd ~/casperjs
- git checkout tags/1.1-beta3
- export PATH=$PATH:`pwd`/bin
- cd -
Goまわりの環境設定
installセクションの中身。GOPATHを設定して、go getで使っているライブラリをダウンロード
- cd $TRAVIS_BUILD_DIR
- export GOPATH=$TRAVIS_BUILD_DIR
- export GOHOME=$GAE
- export PATH=$GAE:$PATH
- which go
- go env
- go get github.com/gorilla/mux
- go get github.com/oleiade/reflections
- go get github.com/russross/blackfriday
開発サーバーを起動
before_scriptのセクション。開発サーバーを立ち上げておきます。
- goapp serve &
- sleep 5
ちなみにcircl ciの場合だと、テストサーバーをあげるときにはbackgroundオプションを付けて実行します。
test:
pre:
- $HOME/go_appengine/goapp serve:
background: true
ローカルテストの実行
scriptのセクション。
- goapp test;casperjs --pre=caspertests/helpers/adminlogin.coffee test caspertests/tests
デプロイ
after_successのセクション。
通常だとgoapp deployでいいですが、OAuth2トークンとか使うとか、ApplicationIDを上書きするとかのオプションを使うためにpythonのコマンドを使います
- python $GAE/appcfg.py update . --oauth2_refresh_token=$GAE_OAUTH -A dev-goappstarter
GAE環境でもテスト
after_scriptのセクション。GAEはローカルサーバーと本番でけっこう動きが違ったりもするので、GAE環境でもテストを走らせておきます。
実行結果
githubにpushすると自動実行されます。
その他
GAE/Python歴は割と長いのですが、Goはほぼ初心者です。GAE/Goでウェブアプリの土台を作ってみたので、書き方等でツッコミいただけるとうれしいです。
最初、Martiniで始めて、Gojiとか使ったりしつつ、今はGorilla/muxをベースに作っています。
DatasotreのREST APIを作るために、reflectionとかゴリゴリ使ってしまったのですが、これはあまり良くなさそう。
なので、また作り直しを検討中。
次は、beegoのgae版( https://github.com/astaxie/beegae )をベースに、作ろうかと検討中です。