Шаблон репозитория 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).
Планы делим на 2 категории:
-
Проверяющие решение (solution)
-
Проверяющие конвейер (pipeline)
Решение проверяем во всех окружениях, в которых его могут эксплуатировать клиенты.
Запускаем анализ зависимостей, линтинг, статический анализ, компиляцию, модульные тесты и собираем/публикуем бинарники.
Все перечисленное ранее. Плюс запускаем интеграционные тесты, анализируем покрытие и собираем/публикуем образы.
-
Почему обязательными статусными проверками назначены тестовые отчеты, а не тестовые джобы?
Это дает свободу выбора структуры джобов, т.к. в различных планах сборки она может быть разной.
-
Релизная сборка
-
Параллелизация модульных тестов
-
Построение дерева хешей (взглянуть критически)
-
Версионирование библиотек и приложений (взглянуть критически)
-
Агрегация отчетов покрытия (взглянуть критически)
-
Локальные проверки в удаленном репозитории
-
Чистка пакетов в удаленном репозитории
-
Поддержка нескольких версий Java