継続的インテグレーション¶
ソフトウェア開発において、作業内容に対する即時フィードバックを得られることは、最も重要な特性の1つと言えるでしょう。ソースコードに1つ変更を加えて、それが何かを壊したかどうかを確認するために2週間待たなければならないと想像してみてください。ああ!それは悪夢でしょう!これを防ぐために、継続的インテグレーションは、チームが構築しているもののステータスについて、即時かつ頻繁にフィードバックを得るのに役立ちます。
Martin Fowlerは継続的インテグレーションを、*チームメンバーが頻繁に作業を統合するソフトウェア開発プラクティスであり、通常は少なくとも1日に1回は各人が統合します。そのため、1日に複数回の統合が行われます。各統合は、統合エラーをできるだけ早く検出するために、自動ビルド(テストを含む)によって検証されます。多くのチームは、このアプローチによって統合の問題が大幅に削減され、チームがより迅速にまとまりのあるソフトウェアを開発できることを発見しています。*と定義しています。
次のサブセクションでは、2つの継続的インテグレーションツール、GitHub ActionsとCircle CIを紹介し、Crystalのサンプルアプリケーションで使用します。
これらのツールは、ソースが変更されるたびにコードをビルドしてテストできるだけでなく、結果をデプロイしたり(ビルドが成功した場合)、自動ビルドを使用したり、異なるプラットフォームに対してテストしたりすることもできます(例を挙げるとすれば)。
サンプルアプリケーション¶
サンプルアプリケーションとして、コンウェイのライフゲームを使用します。より正確には、コンウェイのライフゲームKataソリューションの最初のイテレーションのみを、TDDを使用して使用します。
例自体ではTDDを使用しないことに注意してください。ただし、サンプルコードが最初のイテレーションの結果であるかのように模倣します。
もう1つ重要なことは、crystal init
を使用してアプリケーションを作成することです。
実装は次のとおりです。
class Location
getter x : Int32
getter y : Int32
def self.random
Location.new(Random.rand(10), Random.rand(10))
end
def initialize(@x, @y)
end
end
class World
@living_cells : Array(Location)
def self.empty
new
end
def initialize(living_cells = [] of Location)
@living_cells = living_cells
end
def set_living_at(a_location)
@living_cells << a_location
end
def is_empty?
@living_cells.size == 0
end
end
(コードの内容は原文のまま)
require "./spec_helper"
describe "a new world" do
it "should be empty" do
world = World.new
world.is_empty?.should be_true
end
end
describe "an empty world" do
it "should not be empty after adding a cell" do
world = World.empty
world.set_living_at(Location.random)
world.is_empty?.should be_false
end
end
(コードの内容は原文のまま)
これで、継続的インテグレーションの例に必要なものはすべて揃いました!始めましょう!
継続的インテグレーション ステップバイステップ¶
- 実現したい項目のリストは次のとおりです。
- 3つの異なるCrystalバージョンを使用して、ビルドとスペックの実行を行う
- 最新版
- ナイトリービルド
- 0.31.1 (Dockerイメージを使用)
- shardsパッケージをインストールする
- バイナリ依存関係をインストールする
- データベース(例:MySQL)を使用する
ビルドを高速化するために依存関係をキャッシュする
- ここから次の手順を選択してください
- GitHub Actionsを使用したい