はじめに
- GithubのPull RequestをフックにHerokuのReview appsを自動Deployするパイプラインを構築した際に悩んだ事を備忘としてまとめています。
(My)環境
- DjangoアプリをHerokuでホストしており、DBとしてHeroku Postgresを利用
デリバリー
- Gitのブランチ運用(戦略)はGitHub Flowを採用。
- Herokuパイプラインを構築しており、Review AppのParent AppはStating Appを指定、
- Staging AppがGithubのmasterと同期しており、Production AppはPromote to productionの手動実行によりDeploy
- ソースコードはGithubでホストしており、Githubのmasterに対するプルリクエストをトリガーにReview AppがDeployされる。
- Review Appで動作を確認後、Pull Requestをmasterへmerge。
- masterへmergeされると、masterブランチの更新をフックにHerokuのStating AppがDeployされる。
- Staging Appで動作を確認後、HerokuパイプラインのPromote to productionボタンにより、Production AppがDeployされる。
悩んだ事
- Review Appにも当然AddonとしてPostgresを利用しており、工夫せずビルドすると、DBが空の状態でDeployされ、manage.py migrateが必要だったり、CreateSuperUserしたりと一手間必要となる。
- またPull Requestの内容によっては、テストデータが合った方が良い場合、無い方が良い場合が存在する(と考えられる)
アプローチ
- Reviewの都度、手動実行する事は現実的ではなく、HerokuではReview Appの振る舞いを決めるapp.jsonによってDeploy後に発生する手動作業を軽減出来る。
- app.jsonによりテストデータ有りの場合、無しの場合の振る舞いを再現する。
やってみた
テストデータ無し(migrateのみ実行する)
- env(Config Vars)は意識せず、scriptsのみで完結。
- この場合、テストデータが存在しない状態になる。
app.json
(略)
"scripts": {
"postdeploy": "python manage.py migrate"
},
(略)
- https://devcenter.heroku.com/articles/github-integration-review-apps
- 上記の通りHeroku公式によると、test dataをreview appにloadする際にもpostdeployを利用せよとの事なので以下を
テストデータ有り(stating appのデータをreview appにリストアする)
- staging appのConfig varsにはpostgresのデフォルトKey名として「DATABASE_URL」が採用されている。
- app.jsonではConfig varsの値をscripts内で参照し、コマンド実行する事が可能。
- Config Vars(env)の値にはStringしか設定できないため、単純にStaging AppのDABATASE_URLをReview AppのDATABASE_URLに設定という記述をenvに閉じて実行する事は出来ない。(っぽい)
- よって、scripts内でParent App(Statging App)のDATABASE_URLをReview AppのDATABASE_URLに設定する為に以下のようにする。
- Staging AppのDATABASE_URLの値をコピーし、STG_DATABASE_URLとして設定
2. app.jsonのenv及びpostdeployで以下のように指定
app.json
(略)
"env": {
"STG_DATABASE_URL": {
"required": true
},
"HEROKU_APP_NAME": {
"required": true
}
},
"formation": {
"web": {
"quantity": 1
}
},
"scripts": {
"postdeploy": "pg_dump $STG_DATABASE_URL | psql $DATABASE_URL"
},
(略)
まとめ
- app.jsonをブランチにPushする際にテスト内容に応じ都度変更していく事は手間であるため、テストデータ有りを前提としつつテストデータが不要な場合は、Reset Databaseを実行する。