Гайд по CI/CD в Lowcode Platform
Этот документ объясняет, как устроены GitHub Actions-пайплайны в проекте: какие workflow существуют, что они проверяют, как связаны с Docker-окружениями и Cloudflare Pages, и как локально повторить шаги CI.
1. Общая архитектура CI/CD
Сейчас в репозитории настроены четыре основных workflow:
- CI - PR Lint & Build — проверка pull request’ов (линт + сборка).
- CI - Push Lint & Build — проверки на пуши в основные ветки и feature-ветки.
- API e2e (docker-compose.test) — e2e-тесты API в Docker-окружении.
- Deploy Docs to Cloudflare Pages — сборка и деплой документации на Cloudflare Pages.
Все они лежат в каталоге:
.github/workflows/
api-e2e.yml
ci-pr.yml
ci-push.yml
docs-deploy.yml
Логика примерно такая:
- PR → ci-pr.yml — быстро ловим ошибки линтера и сборки до слияния.
- Push → ci-push.yml — не даём протолкнуть в main/develop/feature/** что-то, что не собирается.
- API e2e → api-e2e.yml — прогоняем e2e API-тесты в том же Docker-контуре, что и локально.
- Docs → docs-deploy.yml — собираем доку и деплоим на Cloudflare Pages при пуше в main.
2. Где лежат workflow и что в них общего
Все workflow используют одинаковую базовую схему:
- запуск на ubuntu-latest;
- checkout репозитория через
actions/checkout@v4; - установка pnpm через
pnpm/action-setup@v4; - установка Node.js 22 через
actions/setup-node@v4с кешемpnpm; pnpm install --frozen-lockfileдля детерминированной установки зависимостей.
Это позволяет максимально переиспользовать кэш зависимостей и ускорять CI.
3. CI для PR: .github/workflows/ci-pr.yml
Файл:
.github/workflows/ci-pr.yml
3.1. Триггеры
Workflow срабатывает на события:
on:
pull_request:
branches:
- main
- develop
То есть любой PR в main или develop автоматически запускает pipeline.
3.2. Джоба lint-and-build-pr
Единственная джоба:
jobs:
lint-and-build-pr:
runs-on: ubuntu-latest
Основные шаги (после checkout и установки Node/pnpm):
-
Установка зависимостей:
- name: Install dependencies
run: pnpm install --frozen-lockfile -
Линт монорепозитория (turbo):
- name: Lint (turbo)
run: pnpm lint:ci -
Сборка (turbo):
- name: Build (turbo)
run: pnpm build:ci
Ожидается, что в корне настроены команды:
pnpm lint:ci
pnpm build:ci
которые через Turborepo гоняют линт и сборку всех нужных пакетов/приложений.
Идея: PR не проходит, если хотя бы один пакет не линтится или не собирается.
4. CI на пуши: .github/workflows/ci-push.yml
Файл:
.github/workflows/ci-push.yml
4.1. Триггеры
Workflow срабатывает на:
on:
push:
branches:
- main
- develop
- 'feature/**'
То есть pipeline запускается при любом пуше в:
maindevelop- любые ветки, начинающиеся с
feature/(удобно для фичевых веток).
4.2. Джоба lint-and-build
По шагам джоба почти полностью зеркалит ci-pr.yml:
checkoutрепозитория;Setup pnpm(pnpm/action-setup@v4);Setup Node 22(actions/setup-node@v4с кешемpnpm);pnpm install --frozen-lockfile;pnpm lint:ci;pnpm build:ci.
Таким образом, любые пуши в ключевые ветки проходят через тот же линт и сборку, что и PR.
5. E2E API пайплайн: .github/workflows/api-e2e.yml
Файл:
.github/workflows/api-e2e.yml
5.1. Триггеры
Workflow срабатывает на:
on:
push:
branches: [main]
pull_request:
branches: [main]
То есть e2e-тесты запускаются:
- при любом пуше в
main; - для любых PR, нацеленных в
main.
5.2. Джоба api-e2e
Джоба использует Docker test-окружение, описанное в infra/docker/docker-compose.test.yml.
Шаги:
-
Checkout репозитория:
- name: Checkout repo
uses: actions/checkout@v4 -
Запуск
docker-compose.test:- name: Run docker-compose.test
run: |
docker compose -f infra/docker/docker-compose.test.yml up --build --abort-on-container-exitЗдесь
api-testконтейнер внутри compose:- накатывает миграции;
- прогоняет unit-тесты API;
- запускает e2e-тесты.
Флаг
--abort-on-container-exitвыключает остальные контейнеры (например, Postgres), когдаapi-testотработал. -
Очистка окружения (всегда):
- name: Teardown docker-compose
if: always()
run: |
docker compose -f infra/docker/docker-compose.test.yml down --volumesТак мы гарантируем, что после завершения job все контейнеры и volume тестового окружения удалены.
Детали test-окружения и структуры Docker-файлов подробно описаны в отдельном гайде по Docker (
infra/docker/…).
6. Деплой документации: .github/workflows/docs-deploy.yml
Файл:
.github/workflows/docs-deploy.yml
Этот workflow отвечает за:
- генерацию справочников через typedoc;
- сборку сайта документации на Docusaurus;
- деплой собранного сайта на Cloudflare Pages.
6.1. Триггеры
on:
push:
branches:
- main
pull_request:
branches:
- main
- push в
main→ полный цикл: сборка + деплой; - PR в
main→ только проверка, что дока собирается, без деплоя.
6.2. Джоба build-and-deploy
Последовательность шагов:
-
Checkout репозитория:
- name: Checkout repository
uses: actions/checkout@v4 -
Установка pnpm:
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
run_install: false -
Установка Node.js 22 с кэшем pnpm:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm -
Установка зависимостей:
- name: Install dependencies
run: pnpm install --frozen-lockfile -
Генерация reference-документации:
- name: Generate reference docs
run: pnpm docs:refЗдесь ожидается команда, которая пробегает по пакетам монорепы и собирает typedoc-справочники в директориях
apps/docs. -
Сборка Docusaurus:
- name: Build Docusaurus
run: pnpm docs:buildВ результате в
apps/docs/buildпоявляется статический сайт. -
Деплой на Cloudflare Pages (только на push в main):
- name: Publish to Cloudflare Pages
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
uses: cloudflare/pages-action@v1
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
projectName: lowcode-docs
directory: apps/docs/build
branch: main
gitHubToken: ${{ secrets.GITHUB_TOKEN }}
6.3. Связка с Cloudflare
Для работы этого шага в настройках репозитория GitHub должны быть заданы секреты:
CLOUDFLARE_API_TOKEN— API-токен с доступом к Pages;CLOUDFLARE_ACCOUNT_ID— ID аккаунта Cloudflare;- стандартный
GITHUB_TOKENпредоставляется GitHub автоматически.
Поле projectName: lowcode-docs должно совпадать с названием проекта на Cloudflare Pages.
7. Как это связано с Docker
api-e2e.ymlнапрямую используетinfra/docker/docker-compose.test.yml.- Dev/test Docker-окружения описаны в отдельном гайде по Docker, но ключевая идея — локально и в CI запускается один и тот же compose-файл.
Это даёт:
- повторяемость среды (одинаковая версия PostgreSQL, одни и те же env-переменные);
- минимизацию «оно работает у меня локально, но падает в CI»;
- возможность локально воспроизвести падение e2e-джобы одной командой.
8. Как локально повторить шаги CI
8.1. Линт и сборка (как в ci-pr / ci-push)
# Из корня монорепозитория
pnpm install --frozen-lockfile
pnpm lint:ci
pnpm build:ci
Если эти команды проходят локально, то соответствующие CI job, скорее всего, тоже будут зелёными (при условии, что окружение не сильно различается).
8.2. E2E API-тесты (как в api-e2e)
Быстрый способ прогнать всё то же самое, что делает CI:
# Чистый старт
docker compose -f infra/docker/docker-compose.test.yml down -v
# Запуск тестового окружения (аналог шага в GitHub Actions)
docker compose -f infra/docker/docker-compose.test.yml up --build
Либо по частям (как описано в Docker-гайде):
# Поднять только БД
docker compose -f infra/docker/docker-compose.test.yml up -d db
# Прогнать тесты
docker compose -f infra/docker/docker-compose.test.yml run --rm api-test
# Очистить окружение
docker compose -f infra/docker/docker-compose.test.yml down -v
8.3. Сборка документации (как в docs-deploy)
pnpm install --frozen-lockfile
pnpm docs:ref
pnpm docs:build
После этого статический сайт документации будет лежать в apps/docs/build.
9. Потенциальное развитие CI/CD
Текущее состояние пайплайнов — базовый, но уже рабочий контур:
- PR и пуши проверяются на линт и сборку.
- API проходит e2e-тесты в Docker-окружении.
- Документация автоматически деплоится на Cloudflare Pages при пуше в
main.
Дальше можно развивать:
-
Отдельные job’ы для unit-тестов (например,
pnpm test:ci+ отчёты coverage). -
Разделение пайплайнов по пакетам (builder-web, api, runtime-host и т.д.) через Turborepo-пайплайны.
-
Release-пайплайн:
- автоматическая генерация changelog;
- создание GitHub Release на теги;
- публикация Docker-образов в registry.
-
Дополнительные проверки для docs (линт Markdown, проверка ссылок, орфография и т.д.).
Но уже сейчас CI/CD закрывает минимально необходимый контур: ничего не попадает в главные ветки, не пройдя базовых проверок, API e2e, а документация уезжает на прод автоматически.