GAE/GoのWebアプリをTravisCIで自動テスト＆自動デプロイする


[GAE/GoのWebアプリをCircleCIで自動テスト&自動デプロイする](http://qiita.com/kyokomi/items/84af37e9774faf9072ed)を見かけたので、OSSなら無料で使えるTravisCI版を書いておきます。

# .travis.yml全体

※2015/01/28追記 [GAE/GoでAppStoreのレビューをSlackに通知してくれるやつ作った](http://qiita.com/yosukesuzuki/items/380669d7ddaf7e579821#gae%E3%81%AE%E7%89%B9%E6%AE%8A%E5%AF%BE%E5%BF%9C)で紹介しているほうが少し新しくなっていますので、そちらも参照してください。

せっかちな人向けに先に設定結果を置いておきます。

こっちのリポジトリにも置いてあります。
https://github.com/yosukesuzuki/go-malt

```.travis.yml
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にします。

![Screen_Shot_2014-10-13_at_17_33_21.png](https://qiita-image-store.s3.amazonaws.com/0/45686/45384182-8c2e-786a-b8f8-92599ebc79a9.png "Screen_Shot_2014-10-13_at_17_33_21.png")

# refresh_tokenを用意する
[CircleCI版](http://qiita.com/kyokomi/items/84af37e9774faf9072ed#refresh_token%E3%82%92%E7%94%A8%E6%84%8F%E3%81%99%E3%82%8B)のほうに説明があるので、そちらを参照してください。

# refresh_tokenを暗号化する
open sourceとはいえ、誰でも本番環境にデプロイできてしまうと困りますよね。

そのために、TravisCIには暗号化という手段が用意されています。
詳しくは[Travisのドキュメント](http://docs.travis-ci.com/user/encryption-keys/)を参照してください。

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はマイナーバージョンの１つ前ぐらいしか、取得できなくなるので、久しぶりにテストを通そうとするとここがだいたい落ちます。自動的にlatestバージョンを追っかけてくれる方法ないかな？
※追記(2015.02.26)ありました、[新しい別記事で言及しているのでそちらを参照](http://qiita.com/yosukesuzuki/items/380669d7ddaf7e579821#%E6%9C%80%E6%96%B0%E3%81%AEsdk%E3%82%92%E5%8F%96%E5%BE%97)してください。

```
- 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オプションを付けて実行します。

```circlciの場合
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すると自動実行されます。

![Travis_CI_-_Free_Hosted_Continuous_Integration_Platform_for_the_Open_Source_Community.png](https://qiita-image-store.s3.amazonaws.com/0/45686/3c170f8c-4bb2-3192-99f8-99deb50c00f4.png "Travis_CI_-_Free_Hosted_Continuous_Integration_Platform_for_the_Open_Source_Community.png")

# その他
GAE/Python歴は割と長いのですが、Goはほぼ初心者です。GAE/Goでウェブアプリの土台を作ってみたので、書き方等でツッコミいただけるとうれしいです。

- [Malt](https://github.com/yosukesuzuki/go-malt)
- [Maltのデモサイト](http://go-malt.appspot.com/)

最初、Martiniで始めて、Gojiとか使ったりしつつ、今はGorilla/muxをベースに作っています。

DatasotreのREST APIを作るために、reflectionとかゴリゴリ使ってしまったのですが、これはあまり良くなさそう。

なので、また作り直しを検討中。

次は、beegoのgae版( https://github.com/astaxie/beegae )をベースに、作ろうかと検討中です。