chore: обновить CI для dev-ветки и актуализировать CONTRIBUTING.md
- Добавлен триггер dev в CI со сборочным job (generate + docs:build + build) - Убраны устаревшие шаги: npm run docs, коммит generated/, README_RU.md - Прод-пайплайн: build → version (тег) → docker → deploy - CONTRIBUTING.md переписан под текущую структуру проекта
This commit is contained in:
@@ -2,12 +2,37 @@ name: CI/CD Pipeline
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [main]
|
branches: [main, dev]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
docs:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: "!contains(github.event.head_commit.message, '[skip ci]')"
|
if: "!contains(github.event.head_commit.message, '[skip ci]')"
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 24
|
||||||
|
|
||||||
|
- name: Установка зависимостей
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Генерация артефактов
|
||||||
|
run: npm run generate
|
||||||
|
|
||||||
|
- name: Сборка документации
|
||||||
|
run: npm run docs:build
|
||||||
|
|
||||||
|
- name: Сборка лендинга
|
||||||
|
run: npm run build
|
||||||
|
|
||||||
|
version:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build
|
||||||
|
if: github.ref == 'refs/heads/main' && !contains(github.event.head_commit.message, '[skip ci]')
|
||||||
outputs:
|
outputs:
|
||||||
version: ${{ steps.version.outputs.version }}
|
version: ${{ steps.version.outputs.version }}
|
||||||
steps:
|
steps:
|
||||||
@@ -16,11 +41,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Setup Node.js
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 24
|
|
||||||
|
|
||||||
- name: Версия из package.json
|
- name: Версия из package.json
|
||||||
id: version
|
id: version
|
||||||
run: |
|
run: |
|
||||||
@@ -28,23 +48,6 @@ jobs:
|
|||||||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||||||
echo "Версия: $VERSION"
|
echo "Версия: $VERSION"
|
||||||
|
|
||||||
- name: Генерация docs
|
|
||||||
run: |
|
|
||||||
npm ci
|
|
||||||
npm run docs
|
|
||||||
|
|
||||||
- name: Коммит generated/
|
|
||||||
run: |
|
|
||||||
git config user.name "CI Bot"
|
|
||||||
git config user.email "ci@gromlab.ru"
|
|
||||||
git add generated/ README_RU.md
|
|
||||||
if git diff --cached --quiet; then
|
|
||||||
echo "Нет изменений, пропуск"
|
|
||||||
else
|
|
||||||
git commit -m "docs: обновить generated (${{ steps.version.outputs.version }}) [skip ci]"
|
|
||||||
git push origin main
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Создать тег
|
- name: Создать тег
|
||||||
run: |
|
run: |
|
||||||
VERSION=${{ steps.version.outputs.version }}
|
VERSION=${{ steps.version.outputs.version }}
|
||||||
@@ -58,7 +61,7 @@ jobs:
|
|||||||
|
|
||||||
docker:
|
docker:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: docs
|
needs: version
|
||||||
if: "!contains(github.event.head_commit.message, '[skip ci]')"
|
if: "!contains(github.event.head_commit.message, '[skip ci]')"
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
@@ -92,7 +95,7 @@ jobs:
|
|||||||
type=ref,event=branch
|
type=ref,event=branch
|
||||||
type=sha,prefix=
|
type=sha,prefix=
|
||||||
type=raw,value=latest,enable={{is_default_branch}}
|
type=raw,value=latest,enable={{is_default_branch}}
|
||||||
type=raw,value=${{ needs.docs.outputs.version }}
|
type=raw,value=${{ needs.version.outputs.version }}
|
||||||
|
|
||||||
- name: Build and push
|
- name: Build and push
|
||||||
uses: docker/build-push-action@v5
|
uses: docker/build-push-action@v5
|
||||||
@@ -104,7 +107,7 @@ jobs:
|
|||||||
tags: ${{ steps.meta.outputs.tags }}
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
build-args: |
|
build-args: |
|
||||||
VERSION_TAG=${{ needs.docs.outputs.version }}
|
VERSION_TAG=${{ needs.version.outputs.version }}
|
||||||
provenance: false
|
provenance: false
|
||||||
sbom: false
|
sbom: false
|
||||||
|
|
||||||
|
|||||||
198
CONTRIBUTING.md
198
CONTRIBUTING.md
@@ -4,182 +4,79 @@
|
|||||||
|
|
||||||
## О проекте
|
## О проекте
|
||||||
|
|
||||||
Документационный сайт с правилами и стандартами фронтенд-разработки на Next.js + TypeScript.
|
Сайт-документация архитектуры SLM Design с лендингом.
|
||||||
|
|
||||||
- Движок: VitePress
|
- Лендинг: React + Vite
|
||||||
- Языки: русский (основной), английский
|
- Документация: VitePress
|
||||||
- Русская версия: `docs/ru/`
|
- Язык: русский
|
||||||
- Английская версия: `docs/en/`
|
- Документация: `docs/architecture/`
|
||||||
|
|
||||||
## Команды
|
## Команды
|
||||||
|
|
||||||
| Команда | Что делает |
|
| Команда | Что делает |
|
||||||
|---------|-----------|
|
|---------|-----------|
|
||||||
| `npm run dev` | Локальный сервер разработки |
|
| `npm run dev` | Локальный сервер лендинга |
|
||||||
| `npm run build` | Сборка статического сайта |
|
| `npm run build` | Сборка лендинга |
|
||||||
| `npm run docs` | Генерация `generated/{lang}/RULES.md` — единый файл для AI-ассистентов |
|
| `npm run docs:dev` | Локальный сервер документации |
|
||||||
|
| `npm run docs:build` | Сборка документации |
|
||||||
|
| `npm run generate` | Генерация артефактов (llms.txt, llms-full.txt, ARCHITECTURE.md, ZIP, README) |
|
||||||
|
|
||||||
## Структура файлов
|
## Структура файлов
|
||||||
|
|
||||||
```
|
```
|
||||||
docs/
|
docs/
|
||||||
├── ru/ # Русская версия (основная)
|
├── index.md # Страница навигации по документации
|
||||||
│ ├── index.md # Главная страница
|
└── architecture/ # Разделы архитектуры
|
||||||
│ ├── basics/ # Базовые правила
|
├── index.md # Обзор SLM Design
|
||||||
│ │ ├── tech-stack.md
|
├── layers.md # Слои
|
||||||
│ │ ├── architecture.md
|
├── modules.md # Модули
|
||||||
│ │ ├── code-style.md
|
└── segments.md # Сегменты
|
||||||
│ │ ├── naming.md
|
|
||||||
│ │ ├── documentation.md
|
|
||||||
│ │ └── typing.md
|
|
||||||
│ └── applied/ # Прикладные разделы
|
|
||||||
│ ├── vscode.md
|
|
||||||
│ ├── project-structure.md
|
|
||||||
│ ├── components.md
|
|
||||||
│ ├── page-level.md
|
|
||||||
│ ├── templates-generation.md
|
|
||||||
│ ├── styles.md
|
|
||||||
│ ├── images-sprites.md
|
|
||||||
│ ├── svg-sprites.md
|
|
||||||
│ ├── video.md
|
|
||||||
│ ├── api.md
|
|
||||||
│ ├── stores.md
|
|
||||||
│ ├── hooks.md
|
|
||||||
│ ├── fonts.md
|
|
||||||
│ └── localization.md
|
|
||||||
├── en/ # Английская версия (зеркало ru/)
|
|
||||||
.vitepress/
|
.vitepress/
|
||||||
├── config.ts # Конфигурация VitePress, сайдбары, локали
|
├── config.ts # Конфигурация VitePress, сайдбар
|
||||||
generated/
|
public/
|
||||||
├── ru/RULES.md # Сгенерированный единый файл (ru)
|
├── llms.txt # Карта документации для LLM
|
||||||
└── en/RULES.md # Сгенерированный единый файл (en)
|
├── llms-full.txt # Полная документация в одном файле
|
||||||
concat-md.js # Скрипт генерации RULES.md
|
└── ARCHITECTURE.md # Единый файл архитектуры
|
||||||
|
generate.ts # Скрипт генерации артефактов
|
||||||
|
src/ # Исходники лендинга (React + Vite)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Добавление нового раздела
|
### Добавление нового раздела
|
||||||
|
|
||||||
1. Создать `.md`-файл в нужной папке (`basics/` или `applied/`).
|
1. Создать `.md`-файл в `docs/architecture/`.
|
||||||
2. Добавить пункт в сайдбар — `.vitepress/config.ts` (оба языка, если есть перевод).
|
2. Добавить пункт в сайдбар — `.vitepress/config.ts`.
|
||||||
3. Добавить файл в массив `fileOrder` — `concat-md.js` (для генерации RULES.md).
|
3. Добавить `description` в frontmatter файла — используется для `llms.txt`.
|
||||||
|
4. Запустить `npm run generate` для обновления артефактов.
|
||||||
|
|
||||||
## Два типа документации
|
## Frontmatter
|
||||||
|
|
||||||
### Базовые правила
|
|
||||||
|
|
||||||
**Отвечает на вопрос:** «Каким должен быть любой код?»
|
|
||||||
|
|
||||||
Универсальные стандарты, **не привязанные к конкретной области**.
|
|
||||||
Правило базовое, если оно применимо ко всему коду одинаково: именование переменных, оформление импортов, когда использовать `type` vs `interface`.
|
|
||||||
|
|
||||||
Примеры в базовых правилах допускаются, но служат иллюстрацией принципа, а не инструкцией по конкретной области.
|
|
||||||
|
|
||||||
**Граница:** если правило касается только одной области (только стили, только компоненты, только API) — оно живёт в прикладном разделе, не в базовых.
|
|
||||||
|
|
||||||
### Прикладные разделы
|
|
||||||
|
|
||||||
**Отвечает на вопрос:** «Как работать с X?»
|
|
||||||
|
|
||||||
Полное описание конкретной области: структура файлов, правила, именование, типизация, примеры.
|
|
||||||
|
|
||||||
**Граница:** прикладной раздел не дублирует базовые правила.
|
|
||||||
Если правило уже описано в базовых — прикладной раздел ссылается на него, но не повторяет.
|
|
||||||
|
|
||||||
## Структура прикладного раздела
|
|
||||||
|
|
||||||
Шаблон ниже описывает все допустимые секции. Раздел включает только те секции, которые для него релевантны — пустые секции не создаются.
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
# {Название}
|
|
||||||
|
|
||||||
Краткое описание: о чём раздел и какие аспекты работы с областью он охватывает.
|
|
||||||
|
|
||||||
## Что нужно знать
|
|
||||||
|
|
||||||
Неочевидная информация, которую читатель должен знать перед чтением раздела.
|
|
||||||
Если для раздела нет такой вводной — секция не создаётся.
|
|
||||||
|
|
||||||
## Структура
|
|
||||||
|
|
||||||
Файловая организация: какие файлы создавать и куда класть.
|
|
||||||
Обязательно — дерево файлов через code-block.
|
|
||||||
|
|
||||||
## Правила
|
|
||||||
|
|
||||||
Конкретные требования, специфичные для области. Делятся на две подсекции:
|
|
||||||
|
|
||||||
### Реализация
|
|
||||||
|
|
||||||
Как написан код внутри файла: синтаксис, паттерны, API.
|
|
||||||
Отвечает на вопрос: «Как писать код?»
|
|
||||||
|
|
||||||
Примеры: объявление через `const`, деструктуризация пропсов, формат вызова `cl()`, способ подключения стилей, структура хука.
|
|
||||||
|
|
||||||
### Организация
|
|
||||||
|
|
||||||
Как компонент/модуль встроен в проект: файловые границы, зоны ответственности, экспорт.
|
|
||||||
Отвечает на вопрос: «Где что лежит и за что отвечает?»
|
|
||||||
|
|
||||||
Примеры: один компонент — один файл, вложенные компоненты в `ui/`, логика выносится в `model/`.
|
|
||||||
|
|
||||||
Формат обеих подсекций — маркированный список.
|
|
||||||
Для неочевидных случаев — блоки «Хорошо / Плохо».
|
|
||||||
Если в области нет правил одной из категорий — подсекция не создаётся.
|
|
||||||
|
|
||||||
## Именование
|
|
||||||
|
|
||||||
Соглашения по именам, специфичные для этой области.
|
|
||||||
Только то, что НЕ покрыто в базовом разделе «Именование».
|
|
||||||
|
|
||||||
## Типизация
|
|
||||||
|
|
||||||
Правила типизации, специфичные для этой области.
|
|
||||||
Только то, что НЕ покрыто в базовом разделе «Типизация».
|
|
||||||
|
|
||||||
## Документирование
|
|
||||||
|
|
||||||
Что и как документировать в этой области.
|
|
||||||
Только то, что НЕ покрыто в базовом разделе «Документирование».
|
|
||||||
|
|
||||||
## Примеры
|
|
||||||
|
|
||||||
Полноценные примеры кода.
|
|
||||||
Каждый пример с путём к файлу и пояснениями.
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
### Порядок секций
|
|
||||||
|
|
||||||
Порядок фиксированный: контекст → структура → правила → специализации базовых правил → примеры.
|
|
||||||
|
|
||||||
Логика: читатель сначала понимает «что это», потом «где это лежит», потом «как это делать», и в конце видит полный пример.
|
|
||||||
|
|
||||||
### Секции-расширения базовых правил
|
|
||||||
|
|
||||||
«Именование», «Типизация», «Документирование» в прикладном разделе — это **точки расширения** базовых правил.
|
|
||||||
|
|
||||||
- В базовых описано общее: `camelCase` для переменных, `type` vs `interface`, формат JSDoc.
|
|
||||||
- В прикладном разделе описано специфичное: как именовать CSS-классы (стили), как типизировать пропсы компонентов (компоненты), как документировать хуки (хуки).
|
|
||||||
|
|
||||||
Если для области нет специфики по именованию, типизации или документированию — секция не создаётся.
|
|
||||||
|
|
||||||
## Конвенции оформления
|
|
||||||
|
|
||||||
### Frontmatter
|
|
||||||
|
|
||||||
Каждый `.md`-файл начинается с YAML frontmatter:
|
Каждый `.md`-файл начинается с YAML frontmatter:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
---
|
---
|
||||||
title: Название раздела
|
title: Название раздела
|
||||||
|
description: Краткое описание для llms.txt
|
||||||
---
|
---
|
||||||
```
|
```
|
||||||
|
|
||||||
Значение `title` совпадает с текстом `h1`-заголовка в файле.
|
- `title` — совпадает с `h1`-заголовком в файле.
|
||||||
|
- `description` — кратное описание содержимого страницы, используется при генерации `llms.txt`.
|
||||||
|
|
||||||
|
## Структура страницы документации
|
||||||
|
|
||||||
|
Каждая страница начинается одинаково:
|
||||||
|
|
||||||
|
1. **Заголовок** (`h1`) — совпадает с `title` из frontmatter.
|
||||||
|
2. **Описание раздела** — 1–2 строки сразу после заголовка. Говорит, что это за раздел, какую информацию он описывает и что читатель в нём получит.
|
||||||
|
3. **Определение** (`## Определение`) — для справочных страниц, посвящённых одному термину. Короткая формулировка жирным: что это за сущность и какую роль она играет.
|
||||||
|
4. **Контент** — остальные `h2`-подразделы.
|
||||||
|
|
||||||
|
## Конвенции оформления
|
||||||
|
|
||||||
### Заголовки
|
### Заголовки
|
||||||
|
|
||||||
- Один `h1` на файл — совпадает с `title` из frontmatter.
|
- Один `h1` на файл — совпадает с `title` из frontmatter.
|
||||||
- Сразу после `h1` — вводный абзац (одно-два предложения).
|
- Сразу после `h1` — описание раздела (1–2 предложения).
|
||||||
- Основные секции — `h2`.
|
- Основные секции — `h2`.
|
||||||
- Подсекции внутри `h2` — `h3`.
|
- Подсекции внутри `h2` — `h3`.
|
||||||
- `h4` не используется.
|
- `h4` не используется.
|
||||||
@@ -194,8 +91,6 @@ title: Название раздела
|
|||||||
|
|
||||||
Используются для контрастного сравнения правильного и неправильного подхода.
|
Используются для контрастного сравнения правильного и неправильного подхода.
|
||||||
|
|
||||||
Формат:
|
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
**Хорошо:**
|
**Хорошо:**
|
||||||
|
|
||||||
@@ -217,11 +112,10 @@ title: Название раздела
|
|||||||
|
|
||||||
### Ссылки между разделами
|
### Ссылки между разделами
|
||||||
|
|
||||||
Прикладной раздел может ссылаться на другие разделы, но не дублирует их содержимое.
|
Раздел может ссылаться на другие разделы, но не дублирует их содержимое.
|
||||||
|
|
||||||
## Принципы
|
## Принципы
|
||||||
|
|
||||||
1. **Не дублировать.** Одна мысль живёт в одном месте. Остальные ссылаются.
|
1. **Не дублировать.** Одна мысль живёт в одном месте. Остальные ссылаются.
|
||||||
2. **Базовое vs прикладное.** Если правило применимо ко всему коду — оно базовое. Если только к одной области — прикладное.
|
2. **Пустые секции не создавать.** Если для раздела нет специфики — секция не создаётся.
|
||||||
3. **Пустые секции не создавать.** Если для раздела нет специфики по именованию — секции «Именование» в нём нет.
|
3. **Примеры обязательны.** Раздел без примеров кода — незавершён.
|
||||||
4. **Примеры обязательны.** Прикладной раздел без примеров кода — незавершён.
|
|
||||||
|
|||||||
Reference in New Issue
Block a user