Skip to content

Latest commit

 

History

History
85 lines (54 loc) · 6.65 KB

README.adoc

File metadata and controls

85 lines (54 loc) · 6.65 KB

bezmen

Шаблон репозитория backend-проекта на Java.

Ключевые принципы

Решение и конвейер как сущности первого класса

Решение (solution) - система, реализуемая для клиентов. Конвейер (pipeline) - система, реализуемая для разработчиков.

Единый интерфейс для локальной разработки и непрерывной интеграции

Семантика интерфейса подразумевает набор предопределенных абстракций, артефакты которых последовательно конструируются в ходе сборки. Перед началом конструирования выполняются обязательные проверки. Примеры абстракций: исходники (sources), бинарники (binaries), образы (images), стеки (stacks) и другие.

Контентная адресация (aka идентификация по содержимому)

Контентная адресация (content addressability) делает конструирование идемпотентным. Для директорий с исходным кодом вычисляются их контентные идентификаторы (CID’s). Затем вычисляются корневые идентификаторы решения и конвейера. Таким образом формируется 2 небольших дерева Меркла, хеши которых подставляются в качестве тегов/классификаторов артефактов соответствующих абстракций. Артефакт конструируется, только когда его контентный идентификатор меняется.

Множественность окружений, назначений и настроек

Решение/конвейер используется клиентами/разработчиками в разных окружениях (environs) для разных назначений (usages) и с разными настройками (prefs). Ключевые окружения/назначения/настройки именуются и проверяются в рамках непрерывной интеграции. Устаревшие окружения/назначения/настройки снимаются с поддержки.

Тесты! Тесты! Тесты!

Тестирование - один из самых важных (или даже самый важный) аспектов разработки! При тестировании проверяется поведение целевого объекта в различных ситуациях. В зависимости от подхода к подготовке зависимостей целевого объекта тесты можно разделить на 3 категории.

Модульные тесты (unit tests)

Все зависимости целевого объекта глушатся (stub) или мокируются (mock).

Интеграционные тесты (integration tests)

Все зависимости глушатся/мокируются кроме одной (иногда нескольких), которая честно конструируется.

Сквозные тесты (end-to-end tests)

Все зависимости честно конструируются.

Роботизированная асинхронная заливка (merge)

Позволяет избежать ошибок/конкуренции и, как следствие, неоправданных потерь на загруженных ветках (например, таких как main).

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

Планы делим на 2 категории:

  1. Проверяющие решение (solution)

  2. Проверяющие конвейер (pipeline)

Проверка решения

Решение проверяем во всех окружениях, в которых его могут эксплуатировать клиенты.

В пределах разумного (sanity)

Запускаем анализ зависимостей, линтинг, статический анализ, компиляцию, модульные тесты и собираем/публикуем бинарники.

Убедительная (convincing)

Все перечисленное ранее. Плюс запускаем интеграционные тесты, анализируем покрытие и собираем/публикуем образы.

За пределами сомнений (beyond doubt)

Все перечисленное ранее. Плюс запускаем сквозные тесты, собираем/публикуем решения.

Проверка конвейера

Конвейер проверяем во всех окружениях, в которых его могут эксплуатировать разработчики.

В пределах разумного (sanity)

Запускаем линтинг исходного кода конвейера.

За пределами сомнений (beyond doubt)

Запускаем весь конвейер на минимальном наборе тестов.

Частые вопросы (FAQ)

  1. Почему обязательными статусными проверками назначены тестовые отчеты, а не тестовые джобы?

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

Консольный интерфейс (CLI)

ansible-playbook <abstraction>.yml [-l <selector>]

Todo

  1. Релизная сборка

  2. Параллелизация модульных тестов

  3. Построение дерева хешей (взглянуть критически)

  4. Версионирование библиотек и приложений (взглянуть критически)

  5. Агрегация отчетов покрытия (взглянуть критически)

  6. Локальные проверки в удаленном репозитории

  7. Чистка пакетов в удаленном репозитории

  8. Поддержка нескольких версий Java