跳至內容

持續整合

對我們正在開發的項目能有即時的回饋,應該是軟體開發最重要的特性之一。想像一下,如果對程式碼進行一個變更,卻要等 2 個星期才能知道它是否破壞了什麼?喔!那會是一場惡夢!為此,持續整合將幫助團隊對他們正在建構的內容有即時且頻繁的回饋。

Martin Fowler 將持續整合定義一種軟體開發實務,團隊成員頻繁地整合他們的工作,通常每個人至少每天整合一次 - 導致每天多次整合。每次整合都會由自動化的建置(包括測試)驗證,以盡快偵測到整合錯誤。許多團隊發現這種方法可以顯著減少整合問題,並使團隊能夠更快地開發出具有凝聚力的軟體。

在接下來的小節中,我們將介紹兩種持續整合工具:GitHub ActionsCircle 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

這就是我們持續整合範例所需要的一切!讓我們開始吧!

持續整合逐步說明

以下是我們想要達成的項目清單

  1. 使用 3 個不同版本的 Crystal 建置並執行規格
    • latest
    • nightly
    • 0.31.1(使用 Docker 映像檔)
  2. 安裝 shards 套件
  3. 安裝二進制相依性
  4. 使用資料庫(例如 MySQL)
  5. 快取相依性以加快建置速度

從這裡選擇您的下一步