fix: заменить cache-busting через query на Cache-Control заголовок #6

Merged
gromov merged 5 commits from dev into main 2026-05-01 21:42:37 +03:00
2 changed files with 76 additions and 179 deletions
Showing only changes of commit ced6a07398 - Show all commits

View File

@@ -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

View File

@@ -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. **Описание раздела** — 12 строки сразу после заголовка. Говорит, что это за раздел, какую информацию он описывает и что читатель в нём получит.
3. **Определение** (`## Определение`) — для справочных страниц, посвящённых одному термину. Короткая формулировка жирным: что это за сущность и какую роль она играет.
4. **Контент** — остальные `h2`-подразделы.
## Конвенции оформления
### Заголовки ### Заголовки
- Один `h1` на файл — совпадает с `title` из frontmatter. - Один `h1` на файл — совпадает с `title` из frontmatter.
- Сразу после `h1`вводный абзац (одно-два предложения). - Сразу после `h1`описание раздела (12 предложения).
- Основные секции — `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. **Примеры обязательны.** Прикладной раздел без примеров кода — незавершён.