Автоматизация документации: MkDocs Material + GitLab CI-CD + Битрикс. DIY или Сделай сам.. DIY или Сделай сам. docs as code.. DIY или Сделай сам. docs as code. mkdocs.. DIY или Сделай сам. docs as code. mkdocs. mkdocs material.. DIY или Сделай сам. docs as code. mkdocs. mkdocs material. Open source.. DIY или Сделай сам. docs as code. mkdocs. mkdocs material. Open source. Подготовка технической документации.. DIY или Сделай сам. docs as code. mkdocs. mkdocs material. Open source. Подготовка технической документации. продуктовая документация.
Автоматизация документации: MkDocs Material + GitLab CI-CD + Битрикс - 1

Всем привет! В процессе обновления инфраструктуры сопровождения наших программных решений мы получили интересный опыт, которым хотим поделиться. Эта статья не просто пошаговая инструкция, а практический разбор того, как мы выстроили процесс подготовки технической документации на основе MkDocs Material, автоматизировали его через GitLab CI/CD и встроили полученный результат в сайт на Битрикс. Наш опыт окажется полезным тем, кто хочет навести порядок в документации и сделать её частью полноценного dev-процесса.

Предисловие

Наша компания сопровождает несколько интернет‑магазинов на платформе Битрикс, каждый из которых включает собственную линейку программных решений. По всем продуктам необходимо составлять и публиковать актуальную документацию. Ситуация усложнилась после того, как мы перевели наши продукты в OpenSource и выложили их в публичные репозитории GitLab. Теперь документация должна быть актуальна и синхронизирована как на сайте магазина, так и в репозиториях.

Перед нами возникла проблема: как автоматизировать работу с документацией?

Мы начали с определения ключевых требований:

  • Адаптивный веб‑сайт, автоматически генерируемый из текстовых файлов;

  • Версионный и открытый исходный код в репозитории GitLab;

  • Возможность публиковать контент разного формата: от статей о продуктах до постов в блоге и справочных руководств;

  • Развертывание и размещение, желательно бесплатное, с возможностью непрерывного обновления в автоматическом режиме через CI/CD;

  • Динамический контент во время сборки для оперативного изменения дизайна статического сайта;

  • Возможность встраивания цифровых ассистентов с использованием технологий искусственного интеллекта;

  • Перспектива автоматизированного тестирования.

После анализа доступных решений, остановились на MkDocs — генераторе статических сайтов, разработанном специально для документации и использующем разметку Markdown.

Конечно, не обошлось без рассмотрения альтернатив:

  1. Sphinx — это популярный инструмент для создания документации, особенно для проектов на Python. Однако, как и любое другое решение, он имеет свои недостатки. Sphinx использует язык reStructuredText, который является менее интуитивным по сравнению с Markdown. Sphinx не предоставляет встроенных функций для редактирования документации в реальном времени, что затрудняет совместную работу. И он требует больше настроек, что сопровождается большей сложностью в переопределении шаблонов.

  2. Docusaurus — это статический генератор сайтов, предназначенный для упрощения создания, развертывания и ведения документации и веб‑сайтов. Docusaurus показался избыточным для наших задач. Он требует больше усилий для первоначальной настройки, особенно если вы не знакомы с React. Конфигурация может быть более сложной из‑за множества доступных опций.

Еще нам довелось поработать с Gatsby, но на момент его использования этот генератор статических сайтов выдавал слишком упрощенный сайт по сравнению с возможностями MkDocs.

Наша документация на Gatsby

Наша документация на Gatsby

MkDocs показался лучшим вариантом: прост в настройке и использовании, поддерживает адаптивный дизайн и имеет множество тем, интегрируется с GitLab CI/CD для автоматической сборки и публикации документации, а также позволяет расширять функциональность с помощью плагинов. Кроме того, шаблон MkDocs Material предоставляет массу возможностей быстрой организации сайта документации.

Как установить и настроить MkDocs

Следует отметить, что MkDocs написан на Python и в нем используется язык шаблонов Jinja2, который позволяет создавать динамически генерируемые HTML‑страницы с простой и понятной разметкой. В MkDocs шаблоны Jinja2 используются для генерации HTML‑страниц из файлов Markdown. Когда запускается команда mkdocs build, MkDocs обрабатывает Markdown‑файлы, применяет к ним шаблоны Jinja2 и создает статические HTML‑страницы, которые затем можно развернуть на веб‑сервере.

Для тех, кто знаком с Python и менеджерами пакетов, установка MkDocs не представляет сложностей. Вот основные шаги для запуска сервера и генерации статического сайта:

Шаг 1: Подготовка окружения

Для MkDocs требуется последняя версия Python и менеджер пакетов PIP. Убедимся, что у нас есть все необходимое. Откройте командную строку (терминал) и введите:

python --version

Должна отобразиться версия Python. Если команда не работает, потребуется установить Python. Скачайте его с официального сайта. Во время установки не забудьте установить флажок «Add python.exe to PATH» (обычно по умолчанию он не активен). Если у вас установлен Python, убедитесь, что PIP обновлен до последней версии. Для его обновления воспользуйтесь командой:

pip install --upgrade pip

Шаг 2: Установка MkDocs

Для установки MkDocs выполните команду:

pip install mkdocs

После этого проверьте успешность установки с помощью команды:

mkdocs --version

Шаг 3: Создание нового проекта

Для создания нового проекта MkDocs выполните команду:

mkdocs new my-project

где my-project — это имя директории проекта. 

Эта команда создаст следующую структуру файлов:

.
├─ docs/
│  └─ index.md # Домашняя страница по умолчанию
└─ mkdocs.yml # Основные настройки вашего проекта

Перейдите в созданную директорию с помощью команды:

cd my-project

Шаг 4: Запуск локального сервера

MkDocs содержит встроенный сервер разработки. С помощью этого сервера можно просматривать документацию во время работы над ней.

Запустите сервер по команде:

mkdocs serve

Теперь можно открыть http://127.0.0.1:8000 в браузере и увидеть заготовку документации:

Заготовка документации

Заготовка документации

Шаг 5: Минимальная конфигурация

Файл mkdocs.yml содержит основные настройки вашего проекта.

Откройте файл в редакторе:

site_name: Документация

Пока что в файле есть только один параметр site_name, который задает название сайта. Задайте свое название и сохраните файл. После сохранения страница в браузере перезагрузится и отобразится новое название.

Настройка названия сайта

Настройка названия сайта

Пример со структурой нашего конфигурационного файла
site_name: Документация # Отображаемое название сайта (в шапке и title)
site_url: https://trusted.ru/documentation/ # Базовый URL сайта
site_author: digtlab.ru  # Имя автора сайта (добавляется в метатег <meta name="author">)
theme:
  name: material # Используется тема MkDocs Material
  custom_dir: overrides # Кастомные шаблоны/стили в папке `overrides`
  features: # Активированные фичи темы:
    - announce.dismiss  # Закрываемые уведомления
    - content.code.annotate  # Аннотации к коду
    - content.code.copy  # Кнопка копирования кода
    - navigation.tracking  # Отслеживание активного раздела
    - navigation.indexes  # Индексирование навигации
    - navigation.sections  # Группировка разделов
    - search.highlight  # Подсветка результатов поиска
    - search.share  # Кнопка поделиться поиском
    - search.suggest  # Подсказки при поиске
    - toc.follow  # Автопрокрутка оглавления
    - toc.integrate  # Интеграция с навигацией
  font:  # Шрифты
    text: PT sans # Основной шрифт
    code: PT Mono # Моноширинный для кода
  logo: assets/crypto.png # Логотип в шапке
  favicon: assets/crypto.png # Иконка вкладки браузера
  language: ru # Локализация интерфейса
plugins: # Установленные плагины MkDocs
  - search:  # Встроенный поиск
      separator: '[su200b-_,:!=[]()"`/]+|.(?!d)|&[lg]t;|(?!b)(?=[A-Z][a-z])'  # Правила разбиения слов
  - minify:  # Минификация HTML
      minify_html: true  # Включено
hooks: # Хуки
  - overrides/hooks/translations.py
extra: # Дополнительная конфигурация
  generator: false
  status:  # Кастомные статусы для страниц
    new: Recently added
    deprecated: Deprecated
extra_css:
  - stylesheets/extra.css  # Дополнительные CSS-стили
watch:  # Папки для отслеживания изменений при `mkdocs serve`
  - docs
  - overrides
  - mkdocs.yml
markdown_extensions: # Список расширений для парсера Markdown, которые добавляют новые возможности к стандартному синтаксису Markdown
  - abbr  # Сокращения (HTML <abbr>)
  - admonition  # Блоки-уведомления (!!! note)
  - attr_list  # Атрибуты HTML ({: .class })
  - def_list  # Списки определений (<dl>)
  - footnotes  # Сноски ([^1])
  - md_in_html  # Markdown внутри HTML-блоков
  - toc:  # Оглавление
      toc_depth: "1-1"  # Уровни заголовков (только h1)
      permalink: true  # Якорные ссылки
      slugify: !!python/name:pymdownx.slugs.uslugify # Алгоритм генерации якорей для заголовков
  - pymdownx.arithmatex:  # Поддержка LaTeX
      generic: true  # Совместимость с MathJax/Katex
  - pymdownx.betterem:  # Умное выделение (**bold**, _italic_)
      smart_enable: all
  - pymdownx.caret # Вставка символов (^sup^)
  - pymdownx.details  # Сворачиваемые блоки (<details>)
  - pymdownx.emoji:  # Эмодзи
      emoji_generator: !!python/name:material.extensions.emoji.to_svg  # SVG-генератор
      emoji_index: !!python/name:material.extensions.emoji.twemoji  # Библиотека Twemoji
  - pymdownx.highlight:  # Подсветка кода
      anchor_linenums: true  # Якоря для строк
      line_spans: __span  # CSS-классы для строк
      pygments_lang_class: true  # Классы языков
  - pymdownx.inlinehilite  # Подсветка в строке (`code`)
  - pymdownx.keys  # Клавиши (++ctrl+alt+del++)
  - pymdownx.mark  #==Выделение текста==
  - pymdownx.smartsymbols  # Поддержка (c) → ©, (tm) → ™
  - pymdownx.snippets:  # Вставка указанных файлов в конец каждой страницы
      auto_append:
        - includes/mkdocs.md  # Путь относительно папки `docs/`
  - pymdownx.superfences:  # Расширенные блоки кода
      custom_fences:
        - name: mermaid  # Диаграммы Mermaid
          class: mermaid
          format: !!python/name:pymdownx.superfences.fence_code_format
  - pymdownx.tabbed:  # Вкладки
      alternate_style: true  # Альтернативный стиль
      combine_header_slug: true  # Генерация slug для заголовков
      slugify: !!python/object/apply:pymdownx.slugs.slugify
        kwds:
          case: lower
  - pymdownx.tasklist:  # Чекбоксы
      custom_checkbox: true  # Кастомные CSS-классы
  - pymdownx.tilde  # ~~Зачеркивание~~
nav: # Структура сайта
…

Подробнее про конфигурацию файла mkdocs.yml читайте на сайте разработчика.

Шаг 6: Добавление контента

Содержимое документации размещается в директории docs/.

По умолчанию папка docs/ содержит один файл с домашней страницей index.md. Добавьте свои файлы в формате markdown (.md) в эту директорию.

.
├─ docs/
│  └─ index.md
│  └─instructions.md
│  └─setup.md
└─ mkdocs.yml

Откройте браузер и убедитесь, что добавленные файлы отобразились на сайте.

Добавление контента

Добавление контента

По умолчанию MkDocs автоматически формирует структуру сайта из всех файлов каталога docs в алфавитном порядке. Порядок сортировки можно настроить в mkdocs.yml с помощью параметра nav:

site_name: Документация
nav:
  - index.md
  - setup.md
  - instructions.md

Теперь на сайте изменилась очередность страниц:

Настройка навигации

Настройка навигации

Стоит отметить, что MkDocs поддерживает переопределение заголовков, а также многоуровневую навигацию.

Например:

site_name: Документация
nav:
  - Главная: index.md
  - Установка и настройка:
    - Установка: setup/setup.md
    - Настройка: setup/settings.md
  - Инструкции: instructions.md

Как это выглядит на сайте:

Настройка навигации

Настройка навигации

Шаг 7: Построение статического сайта

Когда вы будете готовы к публикации, постройте статический сайт, выполнив команду:

mkdocs build

Результат сохранится в папке site. Эти файлы можно разместить на любом веб-сервере.

Шаблон MkDocs Material и его особенности

MkDocs включает несколько встроенных тем mkdocs и readthedocs, помимо которых существуют сторонние темы, разработанные независимыми командами. Вот полный список тем, которые можно установить с помощью pip.

Пожалуй, самым известной и популярной является тема MkDocs Material, именно ее мы и взяли за основу своего портала документации.

Официальный сайт MkDocs Material

Официальный сайт MkDocs Material

Тема включает адаптивный дизайн, множество функций, таких как навигация по страницам, встроенные поисковые функции и возможность добавления пользовательских элементов. Полный список плагинов и расширений темы, которые мы используем, приведен в примере со структурой нашего конфигурационного файла.

Для установки темы MkDocs Material выполните команду:

pip install mkdocs-material

Чтобы применить тему, добавьте в конфигурационный файл mkdocs.yml:

theme: material
Тема MkDocs Material

Инфраструктура создания и размещения документации (GitLab→MkDocs→Битрикс)

Процесс подготовки и публикации документации выстроен как единая цепочка и охватывает все этапы: от создания текста до его размещения на сайте Битрикс.

Как выглядит схема процесса:

Cхема создания и размещения документации

Cхема создания и размещения документации

Для каждого продукта мы разрабатываем документацию в формате Markdown, а затем размещаем ее в ветке docs/ репозитория продукта. После прохождения всех проверок и согласований, изменения вливаются в основную ветку, откуда и начинается процесс автоматической сборки.

Примеры документации:

После публикации изменений в GitLab запускается процесс переноса документации в репозиторий с предварительно настроенной платформой MkDocs Material. Под «преднастройкой» понимается то, что платформа уже нацелена на генерацию статического сайта под определенный информационный ресурс, там имеются все необходимые доработки по стартовым страницам и стилям. Остается только разместить документацию в каталог docs/ и обновить структуру навигации в файле mkdocs.yml. На выходе получается единый статический сайт со всей документацией, готовой к публикации.

Собранные HTML-страницы проходят обработку, при которой автоматически оборачиваются в PHP-шаблоны с хедерами и футерами сайта Битрикс. После преобразования готовые файлы публикуются на тестовом (dev) или рабочем (prod) сервере в зависимости от ветки GitLab. Подробнее о механизме преобразования и настройке шаблонов расскажем ниже.

Проблемы и решения

1. Кастомизация шаблона MkDocs Material

Создавая собственный сайт, вы неизбежно столкнетесь с необходимостью кастомизации MkDocs Material. Например, вы захотите разместить собственное меню в шапке или сделать футер более информативным. Такая возможность есть и это не так сложно, как может показаться. Давайте разберемся, как это сделать на примере изменения шаблонов header и main.

На портале с документацией нам требовалось перенести строку поиска из заголовка страницы в левую часть над меню с навигацией. Поскольку в правом верхнем углу уже находился стандартный поиск сайта от Битрикс, который мы решили оставить.

Кастомизация шаблона MkDocs Material

Кастомизация шаблона MkDocs Material

Для этого в структуре каталогов шаблона MkDocs Material мы создали каталог overrides. В этом каталоге разместили скрипт main.html и подкаталог partials со скриптом header.html.

.
├── docs/                       # Основная директория с документацией
├── overrides/                  # Кастомные шаблоны и стили
│   ├── partials/               # Переопределенные части шаблонов
│   │   └── header.html         # Кастомный header
│   └── main.html               # Основной шаблон
...

Как написать код для скриптов?

Все очень просто. Мы скачали cкрипты из репозитория c исходными кодами темы, а затем внесли правки.

Вот изменения в файле header.html
{% set class = "md-header" %}
{% if "navigation.tabs.sticky" in features %}
  {% set class = class ~ " md-header--shadow md-header--lifted" %}
{% elif "navigation.tabs" not in features %}
  {% set class = class ~ " md-header--shadow" %}
{% endif %}
<header class="{{ class }}" data-md-component="header">
  <nav class="md-header__inner md-grid" aria-label="{{ lang.t("header") }}">
    <a href="{{ config.extra.homepage | d(nav.homepage.url, true) | url }}"
       title="{{ config.site_name | e }}"
       class="md-header__button md-logo"
       aria-label="{{ config.site_name }}"
       data-md-component="logo">{% include "partials/logo.html" %}</a>
    <label class="md-header__button md-icon" for="__drawer">
      {% set icon = config.theme.icon.menu or "material/menu" %}
      {% include ".icons/" ~ icon ~ ".svg" %}
    </label>
    <div class="md-header__title" data-md-component="header-title">
      <div class="md-header__ellipsis">
        <div class="md-header__topic">
          <span class="md-ellipsis">{{ config.site_name }}</span>
        </div>
        <div class="md-header__topic" data-md-component="header-topic">
          <span class="md-ellipsis">
            {% if page.meta and page.meta.title %}
              {{ page.meta.title }}
            {% else %}
              {{ page.title }}
            {% endif %}
          </span>
        </div>
      </div>
    </div>
    {% if config.theme.palette %}
      {% if not config.theme.palette is mapping %}
        {% include "partials/palette.html" %}
      {% endif %}
    {% endif %}
    {% if not config.theme.palette is mapping %}
      {% include "partials/javascripts/palette.html" %}
    {% endif %}
    {% if config.extra.alternate %}
      {% include "partials/alternate.html" %}
    {% endif %}
    {% if "material/search" in config.plugins %}
      {% include "partials/search.html" %}
      <label class="md-header__button md-icon" for="__search">
        {% set icon = config.theme.icon.search or "material/magnify" %}
        {% include ".icons/" ~ icon ~ ".svg" %}
      </label>
    {% endif %}
    {% if config.repo_url %}
      <div class="md-header__source">{% include "partials/source.html" %}</div>
    {% endif %}
  </nav>
  {% if "navigation.tabs.sticky" in features %}
    {% if "navigation.tabs" in features %}
      {% include "partials/tabs.html" %}
    {% endif %}
  {% endif %}
</header>

Мы убрали блок, который отвечает за отображение элемента поиска, оставив его для мобильной верстки.

Вот изменения в файле main.html
{% extends "base.html" %}

{% block hero %}
<div class="title_container">
  <h1 class="title_main">Документация</h1>
</div>
{% endblock %}

{% block site_nav %}
<!--{% if not (page.meta and page.meta.hide) %}-->
  <div>
      {% if "material/search" in config.plugins %}
        <header class="md-search-nav" data-md-component="header">
          <!-- <div class="md-flex__cell md-flex__cell--shrink"> -->
          <label class="md-header__button md-icon" for="__search">
            {% set icon = config.theme.icon.search or "material/magnify" %}
            {% include ".icons/" ~ icon ~ ".svg" %}
          </label>
          {% include "partials/search.html" %}
          <!-- </div> -->
        </header>
      {% endif %}
    {{ super() }}
  </div>
<!--{% endif %}  -->
{% endblock %}

{% block container %}
{% if page.url == '' %}
  {{ super() | replace('<div class="md-content" data-md-component="content">', '<div class="md-content is_home" data-md-component="content">') | safe }}
{% else %}
    {{ super() }}
{% endif %}

{% endblock %}
{% block content %}
  {{ super() }}
  <div class="md-breadcrumbs-buttons" role="navigation" aria-label="navigation">
    {%- if page.previous_page and page.next_page %}
      <div class="text nav_button">
        <a href="{{ page.previous_page.url|url }}" class="float-left" title="{{ page.previous_page.title }}">Предыдущая</a>
      </div>
      <div class="text nav_button">
        <a href="{{ page.next_page.url|url }}" class="float-right" title="{{ page.next_page.title }}">Следующая</a>
      </div>
    {%- endif %}
    {%- if page.previous_page and not page.next_page %}
      <div class="text nav_button">
        <a href="{{ page.previous_page.url|url }}" class="float-left" title="{{ page.previous_page.title }}">Предыдущая</a>
      </div>
      <div></div>
    {%- endif %}
    {%- if not page.previous_page and page.next_page %}
      <div></div>
      <div class="text nav_button">
        <a href="{{ page.next_page.url|url }}" class="float-right" title="{{ page.next_page.title }}">Следующая</a>
      </div>
    {%- endif %}
  </div>
{% endblock %}
{% block footer %}{# Отключаем footer #}{% endblock %}

Также мы внесли изменения в реализацию кнопок перемещения по содержанию сайта и отключили footer.

2. Несовместимые якоря страниц в GitLab и MkDocs

При работе с документаций в формате Markdown заголовкам автоматически назначаются якорные ссылки. Ссылки упрощают навигацию внутри документа и позволяют создавать перекрестные ссылки между разными документами .

Оказалось, что GitLab и MkDocs используют разные алгоритмы генерации якорных ссылок, что приводит к поломке ссылок при переходе между системами.

В чем различия? 

GitLab приводит заголовок к нижнему регистру, убирает все не буквенно-цифровые символы, заменяет пробелы на дефисы.

Пример:

## Настройка SSL-сертификата  → "настройка-ssl-сертификата"

MkDocs удаляет кириллицу, оставляет только латинские буквы, цифры и дефисы.

Для предыдущего примера MkDocs создаст следующий заголовок:

## Настройка SSL-сертификата  → "#ssl-"

Решение: Для приведения якорей к одному виду мы добавили в файл mkdocs.yml расширение toc с правилом slugify:

markdown_extensions:
  - toc:
      slugify: !!python/name:pymdownx.slugs.uslugify

Интеграция документации в интернет-магазин на Битрикс

Рассмотрим, как интегрировать статический сайт с документацией на MkDocs Material, в интернет-магазин на платформе 1С-Битрикс. В качестве примера используем портал https://trusted.ru/documentation/.

Пример главной страницы статического сайта, созданной по шаблону MkDocs Material:

Портал https://trusted.ru/documentation/

Мы уже рассмотрели проект документации на базе  MkDocs Material. Теперь разберемся с его структурой и настройками CI/CD для автоматической сборки и доставки документации в окружение Битрикс.

В GitLab проект организован следующим образом:

.
├── docs/                   # Основная директория с документацией
├── overrides/              # Кастомные шаблоны и стили
├── extra/
│   ├── template.php        # Шаблон для интеграции с Битрикс
│   └── html-to-php.sh      # Скрипт конвертации
...

В папке docs/ размещаются исходные файлы документации в формате Markdown со стилями MkDocs Material. Именно эти файлы используются для сборки статического сайта.

Папка extra/ содержит скрипт html‑to‑php.sh и шаблон template.php, необходимые для интеграции с Битрикс.

Шаблон template.php обеспечивает обертку вокруг каждой HTML‑страницы, добавляя шапку и подвал сайта.

Пример кода template.php
require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/header.php');
$APPLICATION->SetPageProperty("description", "Официальный сайт ООО «Цифровые технологии»");
$APPLICATION->SetPageProperty("title", "Сайт ООО «Цифровые технологии»");
$APPLICATION->SetTitle("Главная"); 
?>
<style>
  label.md-nav__link::before, label.md-nav__link::after {
    display: none!important;
  }
  .content {
    min-height: initial!important;
  }
</style>
<script>
  function resizeHeader() {
    const r = document.querySelector(':root');
    const h1 = $('#header_shop')?.height() || 0;
    const h2 = $('.md-overlay')?.height() || 0;
    const marginTop = Math.abs(h1 - h2 - 3);
    const additionalMarging = 17; //// ????? нужно для sidebar
    r.style.setProperty('--cryptoarm-marging-top', `${marginTop}px`);
    r.style.setProperty('--cryptoarm-marging-top-sidebar', `${marginTop + additionalMarging}px`);
  }
</script>
<div>
  <?php include ('REPLACEME'); ?>
</div>
<script>  
  // resizeHeader();
  $(window).on( "resize", resizeHeader);
</script>
<?require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php");?>

Скрипт html‑to‑php.sh содержит алгоритм обработки страниц документации, после их преобразования в html. Скрипт создает PHP файлы на основе шаблона из template.php, заменяя в нем строку REPLACEME на имена соответствующих HTML файлов. Каждый новый PHP файл сохраняется в ту же директорию, что и оригинальный HTML файл.

Пример кода html-to-php.sh
#!/bin/bash
template=$(cat template.php)
if [[ -z $template ]]
then
    echo 'template is empty' >&2
    exit 1
fi
find ./../docs -type f -name "*.html" | while read fname; 
do 
    dir=$(dirname -- "$fname")
    filename=$(basename -- "$fname")
    filename_noext="${filename%.*}"
    echo "${template/REPLACEME/$filename}" > "$dir/$filename_noext.php"
done

В результате этой обработки каждая сгенерированная статическая страница дополняется хедером и футером сайта Битрикс и все файлы хранятся в формате PHP с сохранением структуры статического сайта.

В каталоге overrides в проекте, использующем MkDocs Material, размещаются пользовательские файлы и настройки, которые позволяют изменять и настраивать внешний вид и поведение документации. Этот каталог используется для переопределения стандартных стилей, шаблонов и других ресурсов, предоставляемых темой Material для MkDocs. В файле mkdocs.yml конфигурируются основные настройки проекта MkDocs, включая параметры для темы, навигации, расширений и других аспектов.

Процесс сборки документации организован с помощью двухэтапного Dockerfile. На первом этапе мы собираем сайт из исходников, на втором — упаковываем в образ с минималистичным nginx‑сервером.

Пример кода dockerfie
FROM registry.example.ru/mkdocs/mkdocs-material-data:9 as build

ARG CI_COMMIT_BRANCH
ARG CI_JOB_TOKEN
ARG CI_SERVER_HOST
ARG CI_PROJECT_NAMESPACE
ARG CI_PROJECT_NAME

ENV DOCS_PATH /docs
RUN git clone -b ${CI_COMMIT_BRANCH} --single-branch --depth 1   https://gitlab-ci-token:${CI_JOB_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}.git 
    ${DOCS_PATH}
RUN mkdocs build -f ${DOCS_PATH}/mkdocs.yml -d ${DOCS_PATH}/site
FROM flashspys/nginx-static
COPY --from=build /docs/site /static
EXPOSE 80
STOPSIGNAL SIGTERM
CMD ["nginx", "-g", "daemon off;"]

Конвейер CI/CD состоит из трёх стадий:

  1. build  — собирает и сохраняет сайт;

  2. convert — преобразует HTML в PHP с помощью html-to-php.sh;

  3. deploy— выкладывает результат на dev или prod-сервер в зависимости от ветки.

Пример кода gitlab-ci.yml
stages:
  - build
  - convert
  - deploy

workflow:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
      when: never
    - when: always

docs_build:
  stage: build
  tags:
    - mkdocs
  before_script:
    - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
    - export BUILD_VERSION=${CI_COMMIT_BRANCH}-$(date +%Y-%m-%d-%H%M)
    - export LATEST_VERSION=${CI_COMMIT_BRANCH}-latest
    - export DOCS_DIR=$CI_PROJECT_DIR/docs
  script:
    - echo "Building and pushing BUILD_VERSION version for $CI_COMMIT_BRANCH branch"
    - if [ -d "$DOCS_DIR" ]; then rm -Rf $DOCS_DIR; fi
    - >
      docker build 
      --pull 
      --no-cache 
      --tag $CI_REGISTRY_IMAGE:$BUILD_VERSION 
      --build-arg CI_COMMIT_BRANCH=$CI_COMMIT_BRANCH 
      --build-arg CI_JOB_TOKEN=$CI_JOB_TOKEN 
      --build-arg CI_SERVER_HOST=$CI_SERVER_HOST 
      --build-arg CI_PROJECT_NAMESPACE=$CI_PROJECT_NAMESPACE 
      --build-arg CI_PROJECT_NAME=$CI_PROJECT_NAME 
      .
    - docker create --name $BUILD_VERSION $CI_REGISTRY_IMAGE:$BUILD_VERSION
    - docker cp $BUILD_VERSION:/static $DOCS_DIR
    - docker rm -f $BUILD_VERSION
    - docker tag $CI_REGISTRY_IMAGE:$BUILD_VERSION $CI_REGISTRY_IMAGE:$LATEST_VERSION
    - docker push $CI_REGISTRY_IMAGE:$BUILD_VERSION;
    - docker push $CI_REGISTRY_IMAGE:$LATEST_VERSION;
    - docker rmi $CI_REGISTRY_IMAGE:$BUILD_VERSION
    - docker rmi $CI_REGISTRY_IMAGE:$LATEST_VERSION
  artifacts:
    name: docs
    paths:
      - ./docs
    expire_in: never

convert_html_to_php:
  stage: convert
  tags:
    - mkdocs
  needs: ["docs_build"]
  script:
    - cd ./extra && bash html-to-php.sh
  artifacts:
    name: docs-php
    paths:
      - ./docs
    expire_in: never

docs_deploy_dev:
  stage: deploy
  variables:
    GIT_STRATEGY: none
  tags:
    - mkdocs
  needs: ["convert_html_to_php"]
  rules:
    - if: $CI_COMMIT_BRANCH == 'dev'
  script:
    - echo "Deploying dev version"
    - rm -rf /var/www/dev_trusted/documentation/*
    - cp -r ./docs/* /var/www/dev_trusted/documentation

docs_deploy_prod:
  stage: deploy
  variables:
    GIT_STRATEGY: none
  tags:
    - mkdocs
  needs: ["convert_html_to_php"]
  rules:
    - if: $CI_COMMIT_BRANCH == 'main'
  script:
    - echo "Deploying prod version"

Послесловие

Мы интегрировали MkDocs Material и автоматизировали публикацию в Битрикс, создав единую систему документации. Это принесло положительные результаты:

  • Оперативность обновлений: правки доходят до пользователей за считанные минуты.  

  • Снижение нагрузки: нет необходимости дублировать контент для GitLab и Битрикс — всё синхронизируется автоматически.  

  • Гибкость: Markdown дает свободу форматирования, а тема Material обеспечивает современный адаптивный дизайн.  

Эта система — не финальное решение, а гибкая основа, которая будет развиваться вместе с нашими продуктами. Сейчас мы активно работаем над улучшениями. Вводим версионность документации и добавляем выбор продукта. Если у вас есть опыт подобных внедрений, мы будем рады обсудить в комментариях!

Спасибо, что прочитали до конца.

Автор: Olga-Gazizova

Источник

Rambler's Top100