Spec-Zone.ru › Crystal

Непрерывная интеграция

Возможность сразу получать обратную связь о том, над чем мы работаем, должна быть одной из важнейших характеристик разработки программного обеспечения. Представьте, что мы внесли одно изменение в исходный код и должны ждать 2 недели, чтобы узнать, не сломало ли оно что-нибудь. Ох! Это был бы кошмар! Здесь команде поможет непрерывная интеграция: она позволяет получать немедленную и частую обратную связь о состоянии разрабатываемого продукта.

Мартин Фаулер определяет непрерывную интеграцию как практику разработки программного обеспечения, при которой участники команды часто интегрируют свою работу: обычно каждый участник делает это как минимум раз в день, что приводит к нескольким интеграциям в день. Каждая интеграция проверяется автоматической сборкой (включая тестирование), чтобы как можно быстрее обнаружить ошибки интеграции. Многие команды считают, что такой подход значительно сокращает количество проблем с интеграцией и позволяет быстрее разрабатывать согласованное программное обеспечение.

В следующих подразделах мы рассмотрим два инструмента непрерывной интеграции: GitHub Actions и Circle CI, и используем их с примером приложения на Crystal.

Эти инструменты не только позволят нам собирать и тестировать код при каждом изменении исходных файлов, но и развертывать результат (если сборка прошла успешно), использовать автоматические сборки и, например, тестировать код на разных платформах.

Пример приложения

В качестве примера приложения мы воспользуемся игрой «Жизнь» Конвея. Точнее, мы возьмем только первые итерации решения ката «Игра „Жизнь“ Конвея» с использованием разработки через тестирование (TDD).

Обратите внимание: в самом примере мы не будем использовать TDD, а лишь представим, что приведенный код — результат первых итераций.

Также важно упомянуть, что для создания приложения мы используем 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

Это всё, что нужно для примеров непрерывной интеграции! Начнем!

Непрерывная интеграция: пошаговое руководство

Вот список того, чего мы хотим добиться:

  1. Собрать и запустить спецификации с помощью трех разных версий Crystal:
    • последней
    • ночной
    • 0.31.1 (с использованием образа Docker)
  2. Установить пакеты shards
  3. Установить бинарные зависимости
  4. Использовать базу данных (например, MySQL)
  5. Кэшировать зависимости, чтобы ускорить сборку

Выберите, с чего продолжить:

  • Я хочу использовать GitHub Actions
  • Я хочу использовать CircleCI

To the extent possible under law, the persons who contributed to this workhave waived
all copyright and related or neighboring rights to this workby associating CC0 with it.
https://crystal-lang.org/reference/1.2/guides/ci/index.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API