Skip to main content

Гайд по CI/CD в Lowcode Platform

Этот документ объясняет, как устроены GitHub Actions-пайплайны в проекте: какие workflow существуют, что они проверяют, как связаны с Docker-окружениями и Cloudflare Pages, и как локально повторить шаги CI.


1. Общая архитектура CI/CD

Сейчас в репозитории настроены четыре основных workflow:

  1. CI - PR Lint & Build — проверка pull request’ов (линт + сборка).
  2. CI - Push Lint & Build — проверки на пуши в основные ветки и feature-ветки.
  3. API e2e (docker-compose.test) — e2e-тесты API в Docker-окружении.
  4. 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):

  1. Установка зависимостей:

    - name: Install dependencies
    run: pnpm install --frozen-lockfile
  2. Линт монорепозитория (turbo):

    - name: Lint (turbo)
    run: pnpm lint:ci
  3. Сборка (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 запускается при любом пуше в:

  • main
  • develop
  • любые ветки, начинающиеся с feature/ (удобно для фичевых веток).

4.2. Джоба lint-and-build

По шагам джоба почти полностью зеркалит ci-pr.yml:

  1. checkout репозитория;
  2. Setup pnpm (pnpm/action-setup@v4);
  3. Setup Node 22 (actions/setup-node@v4 с кешем pnpm);
  4. pnpm install --frozen-lockfile;
  5. pnpm lint:ci;
  6. 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.

Шаги:

  1. Checkout репозитория:

    - name: Checkout repo
    uses: actions/checkout@v4
  2. Запуск 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 отработал.

  3. Очистка окружения (всегда):

    - 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 отвечает за:

  1. генерацию справочников через typedoc;
  2. сборку сайта документации на Docusaurus;
  3. деплой собранного сайта на Cloudflare Pages.

6.1. Триггеры

on:
push:
branches:
- main

pull_request:
branches:
- main
  • push в main → полный цикл: сборка + деплой;
  • PR в main → только проверка, что дока собирается, без деплоя.

6.2. Джоба build-and-deploy

Последовательность шагов:

  1. Checkout репозитория:

    - name: Checkout repository
    uses: actions/checkout@v4
  2. Установка pnpm:

    - name: Setup pnpm
    uses: pnpm/action-setup@v4
    with:
    run_install: false
  3. Установка Node.js 22 с кэшем pnpm:

    - name: Setup Node.js
    uses: actions/setup-node@v4
    with:
    node-version: 22
    cache: pnpm
  4. Установка зависимостей:

    - name: Install dependencies
    run: pnpm install --frozen-lockfile
  5. Генерация reference-документации:

    - name: Generate reference docs
    run: pnpm docs:ref

    Здесь ожидается команда, которая пробегает по пакетам монорепы и собирает typedoc-справочники в директориях apps/docs.

  6. Сборка Docusaurus:

    - name: Build Docusaurus
    run: pnpm docs:build

    В результате в apps/docs/build появляется статический сайт.

  7. Деплой на 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.

Дальше можно развивать:

  1. Отдельные job’ы для unit-тестов (например, pnpm test:ci + отчёты coverage).

  2. Разделение пайплайнов по пакетам (builder-web, api, runtime-host и т.д.) через Turborepo-пайплайны.

  3. Release-пайплайн:

    • автоматическая генерация changelog;
    • создание GitHub Release на теги;
    • публикация Docker-образов в registry.
  4. Дополнительные проверки для docs (линт Markdown, проверка ссылок, орфография и т.д.).

Но уже сейчас CI/CD закрывает минимально необходимый контур: ничего не попадает в главные ветки, не пройдя базовых проверок, API e2e, а документация уезжает на прод автоматически.