持續整合¶
對我們正在開發的項目能有即時的回饋,應該是軟體開發最重要的特性之一。想像一下,如果對程式碼進行一個變更,卻要等 2 個星期才能知道它是否破壞了什麼?喔!那會是一場惡夢!為此,持續整合將幫助團隊對他們正在建構的內容有即時且頻繁的回饋。
Martin Fowler 將持續整合定義為一種軟體開發實務,團隊成員頻繁地整合他們的工作,通常每個人至少每天整合一次 - 導致每天多次整合。每次整合都會由自動化的建置(包括測試)驗證,以盡快偵測到整合錯誤。許多團隊發現這種方法可以顯著減少整合問題,並使團隊能夠更快地開發出具有凝聚力的軟體。
在接下來的小節中,我們將介紹兩種持續整合工具:GitHub Actions 和 Circle CI,並將它們與 Crystal 範例應用程式一起使用。
這些工具不僅可以讓我們在每次原始碼變更時建置和測試程式碼,還可以在建置成功時部署結果,或使用自動建置,並可能針對不同的平台進行測試,這只是舉幾個例子。
範例應用程式¶
我們將使用康威生命遊戲作為範例應用程式。更精確地說,我們將只使用 康威生命遊戲 Kata 解決方案中的第一個迭代,並使用 TDD。
請注意,我們不會在範例本身中使用 TDD,但我們會模擬範例程式碼是第一個迭代的結果。
另一個需要提及的重要事項是,我們正在使用 crystal init
來建立應用程式。
這是實作
src/game_of_life.cr
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
以及規格
spec/game_of_life_spec.cr
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 建置並執行規格
- latest
- nightly
- 0.31.1(使用 Docker 映像檔)
- 安裝 shards 套件
- 安裝二進制相依性
- 使用資料庫(例如 MySQL)
- 快取相依性以加快建置速度
從這裡選擇您的下一步
- 我想使用 GitHub Actions
- 我想使用 CircleCI