(元の記事は: SBクラウドのテックブログを参照してください)
はじめに
継続的インテグレーション (CI - Continuous Integration) は、開発者が書いたコードを定期的に共通レポジトリへマージし、マージした後のビルド・テストが自動的に実行する開発の手法です。
継続的デリバリー (CD - Continuous Delivery)は 、CIの拡張したもので、デリバリープロセスが追加されます。継続的デリバリーでは、開発したコードが自動的にビルド・テストされ、本番環境へリリース可能な状態へ準備されます。
CI/CDは主に以下のメリット
- 開発生産性を向上
- バグを早期に発見し対処できる
- 更新を迅速に配信
CI/CD実施するメリットが多いため、開発プロセスに導入するのが当たり前となっていると思います。
オンプレミス時代なら、ビルドサーバーやCIサーバーの見積もりや構築・運用しなければならず、CI/CDの導入することが大変だと思いますが、今のクラウドやSaaS時代ならば、CI/CDを容易にできるようになりました。Alibaba Cloud 日本リージョンはCI/CDのサービスはまだサポートしていませんが、他のSaaS系CIツールと組み合わせればCI/CDを実施可能です。
CI/CD構成
CI/CDの試すためにWerckerというツールを使いました。Werckerは、DockerによりCI/CDを実施する自動化プラットフォームです。Werckerの詳細については、qiitaには記事がたくさんあったので興味を持っている方はそちらに参照してください。
設定したい構成は以下の図の通りです
- Githubへコミットします
- Github HookによりCIパイプラインが実行されます
- テストがパスしたら、Alibaba CloudのECSにデプロイされた検証環境へ更新
- デプロイ済みの検証環境ECSからイメージを作成
ステップ4のイメージはAutoScalingへ使用してもよいし、イメージを基づいて本番環境のECSを作成してもよいです。
1のデモ用のレポジトリは https://github.com/telescreen/aliyun-wercker-cicd-demo です。
設定手順
1. プロジェクト設定
git clone git@github.com:telescreen/aliyun-wercker-cicd-demo.git
cat wercker.yml
initial-build:
...
deploy-staging:
...
prepare-production-image:
...
wercker.yml
の中身からパイプラインを3つ存在していることがわかります。それは initial-build
ビルド・テストパイプライン、deploy-staging
パイプライン、と prepare-production-image
パイプラインです。それぞれのパイプラインの実施する作業はsteps
で確認できます。
これらのパイプラインを wercker
管理画面で Add new pipeline
ボタンでパイプラインを追加し、Editor
でパイプラインを繋ぎます。
2. 必要な環境変数を設定する
Wercker
管理画面で、steps
が使用する環境変数を定義します。デモアプリの場合は
- SLACK_URL: 通知用のSlack webhook URL
- SLACK_CHANNEL: 通知チャンネル
- PKEY_PRIVATE: 検証環境へアクセス用の秘密鍵
- STAGING_SERVER_IP: 検証環境のIP
- STAGING_SERVER_FINGERPRINT:
known_hosts
に追加する必要のfingerprint
ECSイメージの作成はaliyuncli
を使ってAPI経由で行うため、prepare-production-image
の個別に環境変数の設定が必要です
aliyuncli に必要となる情報は
- ACCESS_KEY_ID / ACCESS_KEY_SECRET: APIを呼び出す用の鍵
- REGION_ID: ECSにあるリージョン
- INSTANCE_ID: 検証環境のECSインスタンスID
3. パイプラインを実行し、検証環境デプロイ
パイプラインを実行し、結果をわくわく待ちます。
パイプラインをすべて実行し、問題がなければ緑パイプラインが表示されます。
CI/CDパイプラインを実際に動かしてみる
1. 変更してみる
$ git checkout -b develop/feature
editor で cicd.pyを開き、以下のコードを追加
@app.route("/newlist")
def newlist():
entries = model_data()
entries.append({"text": "hi, again"})
return render_template("index.html", entries=entries)
cicd_test.py
を開き、テストコードを追加
def test_newlist(self):
rv = self.app.get('/newlist')
assert b'hi, again' in rv.data
追加したコードを単体テスト実施
(cicddemo) workspace/cicddemo - [develop/new-feature●] » pytest cicd_test.py -k newlist
========================================= test session starts =========================================
platform darwin -- Python 3.6.1, pytest-3.0.7, py-1.4.33, pluggy-0.4.0
rootdir: /Users/tal/workspace/cicddemo, inifile:
collected 3 items
cicd_test.py .
========================================= 2 tests deselected ==========================================
=============================== 1 passed, 2 deselected in 0.40 seconds ================================
2. 変更をレポジトリへプッシュする
$ git add .
$ git commit -m "Add code (for cicd testing)"
$ git push origin develop/new-feature
ソースコードがプッシュされると、wercker
が自動にテストが走らせます。
パイプラインが実行終わったら、ECS側でイメージ作成されていることを確認できます
3. テストでバグ発見したら
よくある、モデルを修正して、単体テストは通りますが、結合テストで問題を発見。
@app.route("/newlist")
def newlist():
entries = model_data()
return render_template("index.html", entries=entries)
def model_data():
return [
{ "text": "Hello" },
{ "text": "world" },
{ "text": "one more" },
{ "text": "hi, again" }
]
これでmodel_data
というモデルレイヤが修正され、単体テストがパスしているように見えますが、結合テストは失敗。
Werckerはそれを見つけてくれます。そして、ステップを開くと詳細エラーの原因がわかります。
そして、Slackへ通知されます
テストを通るように問題を修正してもう一回コミットすると
def test_model_data(self):
rv = cicd.model_data()
assert len(rv) == 4
まとめ
CI/CDは
- 開発生産性を向上
- バグを早期に発見し対処できる
- 更新を迅速に配信
というメリットがあります。
今のクラウド時代なら、WerckerのようなSaaS CIサービスとAlibaba Cloudのようなクラウドサービスを組合せることによって容易にCI/CDパイプラインを実施できます。
CI/CDを見て興奮する気持ちを理解したい方は、是非テストプロジェクトをクローンしてwerckerのパイプラインを見てみてください。