type: standard
layer: arch
object: cicd
aspect: pipeline
form: text
title: "CI/CD Pipeline — стандарт"
status: active
version: 1.0.0
date: 2026-04-11
knowledge_level: У1
parent: arch-deployment-operation.md
deps:
- arch-deployment-operation.md
- arch-platform-policy.md
- arch-security-policy.md
Стандарт определяет: триггеры деплоя, роли approvers, уровни окружений (L2=dev / L3=staging / L4=prod), правила перехода между окружениями.
| Окружение | L-уровень | Кто деплоит | Когда |
|---|---|---|---|
dev |
L2 | разработчик / @coder автономно | при коммите в dev-ветку |
staging |
L3 | @executor + подтверждение оператора | после code review |
prod |
L4 | @executor + явное "да" оператора | после тестирования staging |
Правило: без прохождения dev → staging → prod перескакивать нельзя.
| Триггер | Окружение | Условие |
|---|---|---|
Коммит в dev/ ветку |
dev | автоматически |
Коммит в feature/ ветку |
dev | автоматически |
PR merge в main |
staging | после code review |
| Явная команда оператора | prod | только после "работает, деплоим" |
Хотфикс hotfix/ |
prod | экстренно, L4, с бэкапом |
Условия перехода:
✅ Все тесты прошли (phpunit / pytest / jest)
✅ Code review выполнен (не обязательно внешний — хватает self-review)
✅ Нет конфликтов в базе (миграции применились в dev)
✅ Ресурсы проверены: bash /opt/scripts/check_resources.sh → GREEN
Условия перехода:
✅ Функциональное тестирование на staging завершено
✅ Оператор явно сказал "работает, деплоим"
✅ Бэкап prod выполнен (С2 BACKUP)
✅ Rollback-план готов (docker tag backup-YYYYMMDD)
✅ Время деплоя: рабочее время или по согласованию
Запрещено деплоить в prod:
❌ В пятницу вечером (нет поддержки на выходных)
❌ Без бэкапа БД
❌ Без явного "да" оператора
❌ Если staging не прошёл тесты
| Операция | Кто подтверждает |
|---|---|
| Деплой в dev | никто (автоматически) |
| Деплой в staging | @executor самостоятельно |
| Деплой в prod | Оператор (явное "да") |
| Хотфикс в prod | Оператор (явное "да" + "понимаю риск") |
| Откат prod | Оператор (явное "да") |
| Изменение nginx prod | Оператор (явное "да") |
Approver — единственный, кто произносит явное подтверждение.
@executor только предлагает план и выполняет после "да".
# 1. проверить ресурсы
bash /opt/scripts/check_resources.sh # GREEN
# 2. pull + build
git pull origin dev
docker compose build --no-cache app
# 3. тесты
docker compose run --rm app vendor/bin/phpunit
# 4. запуск
docker compose up -d
# 5. проверка
curl -s -o /dev/null -w "%{http_code}" http://localhost:{port}/
# 1. бэкап текущего состояния
docker tag {service}:latest {service}:backup-$(date +%Y%m%d)
pg_dumpall -U postgres | gzip > "$DATASPACE/backups/db/$(date +%Y%m%d_%H%M)_pre-deploy.sql.gz"
# 2. merge main → staging
git checkout staging && git merge main
# 3. деплой
docker compose pull
docker compose up -d --force-recreate
# 4. миграции
docker compose exec app drush updb -y # для Drupal
# или: alembic upgrade head # для Python
# 5. тесты
docker compose run --rm app vendor/bin/phpunit
# 6. проверка
curl -s -o /dev/null -w "%{http_code}" https://staging.{домен}/
# 0. СТОП — получить явное "да" оператора
# 1. полный бэкап
pg_dumpall -U postgres | gzip > "$DATASPACE/backups/db/$(date +%Y%m%d_%H%M)_pre-prod.sql.gz"
docker tag {service}:latest {service}:backup-$(date +%Y%m%d)
# 2. техническое обслуживание
# (опционально: nginx 503 на время деплоя)
# 3. деплой (аналогично staging)
...
# 4. smoke-tests
curl -s -o /dev/null -w "%{http_code}" https://{домен}/
curl -s -o /dev/null -w "%{http_code}" https://{домен}/health
# 5. снять обслуживание
# 6. мониторинг 15 минут
Экстренное исправление критического бага в prod:
1. СТОП обычного потока
2. Создать ветку: git checkout -b hotfix/{описание}
3. Исправить + минимальный тест
4. Оператор: явное "да, деплоим хотфикс, понимаю риск"
5. Бэкап prod (обязательно)
6. Деплой напрямую в prod (L4)
7. Merge обратно в main и dev
8. Документировать инцидент в system/monitor/alerts/
При ошибке после деплоя → немедленный откат, не диагностировать в prod:
# откат Docker
docker compose down
docker tag {service}:backup-YYYYMMDD {service}:latest
docker compose up -d
# откат базы (если миграции применялись)
# alembic downgrade -1
# drush sqlc < backup.sql (для Drupal)
# проверка
curl -s -o /dev/null -w "%{http_code}" https://{домен}/
Полная матрица откатов: arch-deployment-operation.md §8.
CODE-PROMPT — промежуточный слой между проектированием и кодированием. Агрегирует всё необходимое в один промпт для кодера: задачу, данные, запреты, API, инструкции.
ПРОЕКТИРОВАНИЕ → CACHE.yaml → SPEC.yaml → CODE-PROMPT.md → КОДИРОВАНИЕ
project/
├── CACHE.yaml ← Глобальный кеш (хеши, данные, граф зависимостей)
├── PROJECT.md
├── data/
├── standards/
└── solutions/
└── website/src/module/
├── SPEC.yaml ← Конфигурация модуля
├── CODE-PROMPT.md ← Готовый промпт для кодера (генерируется)
├── prompts/ ← Блоки (если >500 строк)
└── src/
Три уровня данных:
В git: да (история состояния проекта).
task: "Импорт товаров из BAZON"
estimate: "3.5 часа"
data:
source: "@CACHE#extracted.data.bazon_url"
format: "@CACHE#extracted.data.bazon_format"
constraints:
platform: "@CACHE#extracted.standards.cs_cart.constraints"
module:
- "Не использовать глобальные переменные"
dependencies:
- "@../catalog/API.md#get_category"
instructions:
- "Создать lib/normalize.php"
- "Создать lib/categories.php"
check:
- "SELECT COUNT(*) FROM cscart_products = 13347"
Синтаксис ссылок:
- @CACHE#path.to.data — из глобального CACHE
- @../path/file.md — относительный путь к файлу
- @../path/file.md#section — конкретная секция файла
В git: да.
Структура: Задача → Данные → Запреты → API других модулей → Инструкции → Проверка.
В git: нет (генерируется, добавить в .gitignore).
Размер:
| Размер | Действие |
|---|---|
| <500 строк | Один CODE-PROMPT.md |
| 500-1500 строк | Разбить на 2-5 блоков в prompts/ |
| >1500 строк | Пересмотреть декомпозицию модуля |
# Агрегация проекта в CACHE
claude aggregate-project
# Сборка промпта из SPEC + CACHE
claude build-prompt solutions/website/src/import/
# Разбиение большого промпта на блоки
claude split-prompt solutions/website/src/import/
# Проверка актуальности (хеши изменились?)
claude check-cache
# Пересборка устаревших промптов
claude rebuild-stale
# .git/hooks/pre-commit
#!/bin/bash
claude check-cache || claude rebuild-stale
| Роль | Ответственность |
|---|---|
| Проектор | Создать PROJECT.md, data/, standards/, SPEC.yaml |
| Система | Агрегировать в CACHE, собрать CODE-PROMPT |
| Кодер | Читать CODE-PROMPT, писать код |
У0 (Идея) — theory/, concept/ — LOCKED, редко меняется
У1 (Стандарты) — standards/ — Редко меняется
У2 (Паттерны) — patterns/ — По мере накопления
У3 (Шаблоны) — templates/ — Готовые заготовки
У4 (Инстансы) — {project}/ — Конкретные реализации
1. ТРИГГЕР — новая сущность, существенное изменение, запрос оператора
2. ОПРЕДЕЛИТЬ ТИП — уровень (У0-У4), формат (md/yaml), место
3. СОЗДАТЬ/ОБНОВИТЬ — использовать шаблон, заполнить обязательные поля
4. ПРОВЕРИТЬ — версия указана, ссылки работают, нет дублирования
5. ИНТЕГРИРОВАТЬ — добавить в индекс, обновить ссылки, commit
| Ситуация | Действие |
|---|---|
| Новый проект | index.yaml + README.md |
| Новая инфра | INFRA.yaml |
| Архитектурное решение | ADR в design/ |
| Изменение API | Обновить README |
| Баг и решение | Не документировать (git history) |
| Изменение | Версия |
|---|---|
| Исправление опечатки | X.Y.Z+1 (PATCH) |
| Добавление секции | X.Y+1.0 (MINOR) |
| Изменение структуры | X+1.0.0 (MAJOR) |
| Формат | Назначение |
|---|---|
UPPER_CASE.md |
Документы |
kebab-case.ai.md |
AI-агенты |
index.yaml |
Индексы |
README.md |
Точки входа |
Пошаговое развёртывание с проверкой на каждом шаге. Никогда не делать несколько изменений сразу.
1. ПОДГОТОВКА → Проверить синтаксис локально → СТОП: файлы готовы?
2. ЗАГРУЗКА → Загрузить файлы на сервер → СТОП: сайт работает?
3. АКТИВАЦИЯ → Активировать модуль → СТОП: сайт работает?
4. ТЕСТ МИНИМАЛЬНЫЙ → Проверить базовую функцию → СТОП: работает?
5. ТЕСТ ПОЛНЫЙ → Проверить на реальных данных → СТОП: работает?
6. ГОТОВО
Если сломалось и не получается починить за 5 минут:
Если сломалось ВСЁ:
Каждое изменение записывать:
projects/{project}/site/@{domain}/CHANGELOG.md
## YYYY-MM-DD HH:MM
### Действие
- Что сделано
- Какие файлы затронуты
- Результат (ОК / ОШИБКА)
### Откат (если нужен)
- Команды для отката
Тикеты — фиксация проблем, идей и предложений для последующей обработки.
Отличие от задач (.queue/):
- Задачи = конкретные инструкции к выполнению
- Тикеты = проблемы/идеи, требующие анализа
| Приоритет | Описание | Маркер |
|---|---|---|
| CRITICAL | Блокирует работу, немедленно | P0 |
| IMPORTANT | Снижает эффективность, в ближайшее время | P1 |
| IMPROVEMENT | Улучшения, можно отложить | P2 |
| IDEA | Идея для обсуждения | P3 |
| Тип | Префикс | Описание |
|---|---|---|
| BUG | BUG- | Ошибка |
| FEATURE | FEAT- | Новая функция |
| IMPROVE | IMP- | Улучшение существующего |
| IDEA | IDEA- | Идея для обсуждения |
| TECH | TECH- | Технический долг |
| DOC | DOC- | Документация |
/.tickets/
├── open/ ← Открытые
├── in_progress/ ← В работе
├── resolved/ ← Решённые
└── closed/ ← Закрытые
Формат имени: {ТИП}-{NNN}-{slug}.md
Примеры: BUG-001-session-recovery.md, FEAT-002-export-pdf.md
| Статус | Описание |
|---|---|
| OPEN | Новый, не начат |
| IN_PROGRESS | В работе |
| BLOCKED | Заблокирован зависимостями |
| RESOLVED | Решён, ожидает проверки |
| CLOSED | Закрыт, проверен |
| WONTFIX | Не будет исправляться |
# {ТИП}-{NNN}: Краткое название
**Статус:** OPEN
**Приоритет:** P1 (IMPORTANT)
**Создан:** YYYY-MM-DD
**Автор:** Кто создал
**Область:** Где проблема (путь/модуль)
## ПРОБЛЕМА
Описание проблемы или идеи.
## ТЕКУЩЕЕ СОСТОЯНИЕ
Как сейчас работает.
## ПРЕДЛАГАЕМОЕ РЕШЕНИЕ
Как предлагается решить.
## КРИТЕРИИ ПРИЁМКИ
- [ ] Критерий 1
- [ ] Критерий 2
тикет: bug P0 Сессии не сохраняются при сбое
тикет: idea P3 Добавить голосовой интерфейс
Создать файл в /.tickets/open/ → Заполнить по шаблону → Присвоить ID
↓ (взятие в работу)
Переместить в in_progress/ → Обновить статус → Добавить дату начала
↓ (завершение)
Переместить в resolved/ → Заполнить результат
↓ (после проверки)
Переместить в closed/
Любая работа с внешним сервером ведётся через зеркало в workspace. Нет зеркала — нет изменений. Нет бэкапа — нет изменений.
WORKSPACE (git):
projects/org/{project}/deploy/
├── README.md ← что за сервер, как подключаться
├── _backups/ ← бэкапы файлов ДО изменения
│ └── 2026-03-14_module.php
└── {путь от корня сайта}/ ← зеркало файлов сервера
DATASPACE (S3):
projects/{project}/backups/
└── 2026-03-14_db.sql ← дампы БД
1. ЗЕРКАЛО — скопировать с сервера в deploy/
scp user@server:/path/to/file projects/org/{proj}/deploy/path/to/file
2. БЭКАП — сохранить копию
cp deploy/path/file deploy/_backups/YYYY-MM-DD_file
3. ИЗМЕНИТЬ — правим файл в зеркале (в workspace)
4. ДЕПЛОЙ — отправить на сервер
scp deploy/path/file user@server:/path/to/file
5. КОММИТ
git add deploy/ && git commit -m "deploy({project}): что изменили"
1. ДАМП — на сервере
mysqldump -u user -p db_name > /tmp/YYYY-MM-DD_db.sql
2. СКАЧАТЬ в dataspace
scp user@server:/tmp/YYYY-MM-DD_db.sql $DATASPACE/projects/{proj}/backups/
3. МИГРАЦИЯ — выполнить SQL на сервере
4. ПРОВЕРИТЬ — убедиться что всё работает
| Тип файла | Где |
|---|---|
| PHP, конфиги, шаблоны | WORKSPACE deploy/_backups/ |
| Дампы БД (.sql) | DATASPACE backups/ |
| Изображения, медиа | DATASPACE |
| Архивы сайта (.zip) | DATASPACE |
WORKSPACE (разработка): projects/org/{project}/app/{platform}/scripts/
- Полная документация в README.md
- Credentials в .credentials.md (не в коде!)
- Git контроль, примеры использования
ХОСТИНГ (production): ~/project/.scripts/ (скрытая папка внутри проекта)
- Права доступа: chmod 700 (только владелец)
- Реальные credentials
- Веб-доступ автоматически заблокирован (начинается с точки)
~/work.lideravto.ru/
├── .scripts/ ← Скрытая папка (НЕТ веб-доступа)
│ ├── golden_cscart_419.tar.gz ← Золотой бэкап файлов
│ ├── golden_database.sql.gz ← Золотой бэкап БД
│ ├── restore_golden.sh ← Быстрое восстановление (1-2 мин)
│ ├── create_golden.sh ← Создание золотого бэкапа
│ ├── check_installation.php
│ └── clean_database.php
├── admin.php
└── index.php
# 1. Создать скрытую папку на хостинге
ssh user@host
mkdir -p ~/work.lideravto.ru/.scripts
chmod 700 ~/work.lideravto.ru/.scripts
# 2. Загрузить скрипты
scp check_installation.php user@host:~/work.lideravto.ru/.scripts/
# 3. Заменить credentials (PLACEHOLDER → реальные из .credentials.md)
# 4. Установить права
chmod 700 ~/work.lideravto.ru/.scripts/*.php
# 5. Проверить безопасность
curl http://domain.ru/.scripts/check_installation.php
# Ожидаем: 403 Forbidden или 404 Not Found
// WORKSPACE (в git): placeholder
$DB_PASS = getenv('DB_PASS') ?: 'CHANGE_ME';
// ХОСТИНГ (не в git): реальные значения допустимы
$DB_PASS = '8jR*Y!eB0r%G';
Вместо многократной установки движка — один раз создать "золотой бэкап" чистого состояния. Восстановление: 1-2 минуты вместо 30-40 минут.
# Создание (один раз после чистой установки)
./.scripts/create_golden.sh
# Восстановление (для экспериментов)
./.scripts/restore_golden.sh
.credentials.md (НЕ в коде)Скрипты, запускаемые на компьютере оператора одной строкой. Результат отправляется на сервер.
Причина: Длинные inline-команды в чате ломаются при копировании.
bash <(curl -s http://91.218.142.168/files/ИМЯ_СКРИПТА.sh)
#!/bin/bash
# REMOTE SCRIPT STANDARD v1.0
# Запуск: bash <(curl -s http://91.218.142.168/files/ИМЯ.sh)
# Результат: http://91.218.142.168/files/ИМЯ.log
SERVER="http://share.0kt.ru"
LOGNAME="ИМЯ.log"
OUT=""
log() { OUT+="$1\n"; echo "$1"; }
# --- Основная логика ---
log "=== Заголовок — $(date) ==="
log "Host: $(hostname)"
# ... действия и сбор данных через log() ...
# --- Отправить результат на сервер ---
printf "%b" "$OUT" | curl -s -X POST "${SERVER}/push/${LOGNAME}" \
-H "Content-Type: text/plain" \
--data-binary @- > /dev/null
echo "Лог: http://91.218.142.168/files/${LOGNAME}"
| Правило | Описание |
|---|---|
| Одна строка запуска | bash <(curl -s URL) |
| Имя скрипта | задача_действие.sh |
| Имя лога | То же, но .log |
| Вывод через log() | Дублировать: в консоль + в переменную OUT |
| Отправка в конце | POST на /push/ИМЯ.log |
| Идемпотентность | Можно запустить несколько раз без побочных эффектов |
# Следить за логом в реальном времени
bash /opt/scripts/watch_remote.sh chrome_fix.log
# Посмотреть последний результат
cat /var/www/html/files/chrome_fix.log
/var/www/html/files/ ← скрипты и логи (публичный доступ)
/opt/scripts/ ← серверные утилиты (watch_remote.sh)
Родитель:
- arch-deployment-operation.md — протокол деплоя
Связанные:
- arch-security-policy.md — С2 BACKUP, С3 ROLLBACK
- arch-platform-policy.md — П3 СЕРВИСЫ, П4 GIT