Что такое Docs as Code классно описано в статье Docs as Code: введение в предмет.
В двух словах: это ведение документации на языке разметки (Markdown, AsciiDoc) с хранением в репозитории.
Плюшки — все вытекающие от работы с репозиторием.
Минусы — в этой статье.
На осенних Analyst Days прошлого года добрая четверть докладов была посвящена теме Docs as Code. На тот момент конклав аналитиков на моём прежнем месте работы уже 9 месяцев решал, нужен ли на проекте модный-стильный-молодёжный Docs as Code или всё же остаться в дышащем на ладан Confluence. К чему пришли — не знаю. На новом месте работы мы внедрили Docs as Code за неделю — было чёткое понимание проблематики, подход казался выигрышным решением. Используем полгода.
Какие были требования к системе документирования
Обязательные
Развёртывание во внутреннем контуре. Ввиду корпоративной тайны внешние облака были исключены.
Возможность параллельной работы над документом.
Автоматическое отображение дельты изменений.
Автоматическое формирование PDF для представления заказчику.
Возможность переиспользования конкретных блоков из одних документов в других (include).
Возможность согласования документации конкретными людьми.
Отображение документации в полностью скомпилированном виде.
Желательные
Автоматическая подвязка изменений документации к задачам на разработку в системе управления задачами.
Доступ к документации для разработчиком непосредственно из IDE.
Сохранение имеющихся документов, которые были написаны в Markdown и AsciiDoc.
Opensourse для возможности самостоятельной доработки.
Использование PlantUML.
Docs as Code закрывает все эти потребности. И вот как мы это сделали.
Решение
На проекте используются:
Система контроля версий Gitea.
Система управления проектами и задачами Redmine.
Ранее документация велась в Wiki.js. Эта вики поддерживает Markdown, некоторые коллеги предпочитали использовать именно его.
Что выбрали для Docs as Code
Язык разметки AsciiDoc. В отличии от Markdown он поддерживает include и переменные "из коробки".
IDE PyCharm. У него есть бесплатная версия, официальные плагины для AsciiDoc и PlantUML, а заодно неплохая встроенная проверка орфографии и пунктуации русского языка. Субъективно он более дружелюбен к непродвинутому пользователю, чем VS Code.
Hugo для отображения полной документации.
Для использования PlantUml-диаграмм внутри AsciiDoc-документов развернули во внутреннем контуре серверы Kroki и PlantUML.
Сборкой документации после коммита занимается Drone.
Как организовали хранение документации
На проекте сервисная архитектура. У каждого сервиса своя команда разработчиков. Под каждый сервис завели репозиторий документации и раздали соответствующим разработчикам доступы и права аппрувить пулреквесты.
Отдельно завели репозиторий архитектуры. В нём хранится документация, которая затрагивает несколько сервисов: архитектурная схема, перечень очередей сообщений, верхнеуровневые описания межсервисных взаимодействий, proto-моделей (используем gRPC), какие-то общие правила и т.д.
Также завели репозитории под бизнес-требования, организационную и пользовательскую документацию. К ним и к архитектуре доступ дали всем членам команды.
Как организовали процесс работы
Изначально идея заключалась в том, что репозиторий с документацией по сервису будет подтягиваться в корень репозитория соответствующего сервиса, то есть разработчику не нужно отдельно выкачивать реп документации.
Также изначально была идея поддерживать две постоянные ветки документации:
prod — с описанием функциональности системы в состоянии на проде;
dev — с описанием функциональности системы в состоянии реализованных, но ещё не выпущенных доработок.
Документация с учётом отдельных доработок должна была лежать во временных ветках, соответствующих эпикам по бизнес-запросам.
Предполагалось, что пока документация по фиче будет сливаться в ветку dev одновременно с влитием кода в общую ветку, а в prod одновременно с выносом функциональности на прод.
От этих идей мы отказались быстро.
Во-первых, важно было поддерживать ссылочность внутри документов. Причём эти ссылки должны были работать в Hugo. Соответственно мы стали указывать в документах ссылки на предполагаемую страницу документа в Hugo, причём зачастую на этот момент страницы в Hugo не существовало, так как оба документа создавались в рамках одной задачи.
Соответственно если бы разработчик решил читать документацию в IDE, то первая же ссылка перебросила бы его в Hugo. Если бы целевой документ был старым! А если новым, то ссылка вела бы на страницу 404, потому что настраивать сборку Hugo для каждой ветки эпика нецелесообразно.
Во-вторых, изменения требований необходимо согласовывать с разработчиками до начала реализации. Согласовывать можно только пулреквесты. Если бы мы хотели видеть согласованную документацию в ветках эпиков, то пришлось бы почковать ветки и от них тоже.
В-третьих, во время проектирования решения аналитик должен учитывать все актуальные требования. Долгое пребывание документации в ветках эпиков неизменно привело бы к тому, что аналитик не учёл бы требования, которые находятся в ветках других эпиков и ещё не слиты в dev.
В итоге мы остановились на такой схеме:
Аналитик проектирует решение в ветке эпика, после чего презентует его команде разработки на общей встрече и формирует пачку пулреквестов в dev (по 1 в каждом репозитории с изменениями).
Пулреквесты согласуют архитектор, ведущие разработчики затронутых сервисов, тестировщики, ведущий аналитик.
В dev таким образом хранятся все требования, которые были реализованы, уже находятся в разработке, и которые только планируется взять в разработку.
А ветка prod оказалась не нужна, потому что Gitea не позволяет переносить отдельные коммиты, только все накопленные разом. При этом некоторая готовая функциональность может не пойти в релиз сразу. Оставалось править документацию ветки prod вручную, но для этого я недостаточно самоотвержена.
Разработчики видят полную и актуальную документацию в Hugo.
Схема сократилась до:
Казалось бы, всё заработало. Что могло пойти не так?
Грабли
Шишка первая, ожидаемая. Аналитиков пришлось учить работать с git и IDE, писать на языке разметки. Решали проблему пачкой гайдов, блужданием по документации AsciiDoc и иногда методом тыка.
Шишка вторая, о которой все умалчивают. Нагрузка на глазки аналитиков возросла в разы. Мало что садит зрение так же, как код. В бытность программистом я потеряла две диоптрии вопреки всем гимнастикам. Поверьте, заполнение таблички с WYSIWYG резко отличается от контроля количества вертикальных палочек в строке 213. Добавьте сюда повторные правки, когда палочки всё же недосчитали, и таблица превратилась в фарш. А ещё билды, поломанные лишним слешем. Кстати, представьте себе лицо аналитика, который всю жизнь спокойно жал кнопочку "Сохранить" в Wiki, и вдруг уронил билд.
Шишка третья, макулатурная. Количество документов Х2 просто потому, что PlantUML схемы рисуются в отдельном файле, а ещё потому, что в каждой папочке Hugo должен лежать index-файл этой папочки. Представьте себе лицо разработчика, который для согласования единственного метода получает пять файлов.
Шишка четвёртая, эстетическая. Оказалось, что ни Hugo, ни Gitea не поддерживают AsciiDoc из коробки в полной мере. В частности в Hugo некорректно отображаются большие и сложные таблицы — сбоит определение ширины, объединение ячеек, выравнивание в ячейке. Giteа не показывает схемы PlantUML.
Шишка пятая, коммуникационная. В Hugo нельзя просто выделить текст с ошибкой и написать к нему комментарий, как в Confluence. А это значит, что в чаты к аналитикам летит поток со скриншотами или ссылками на текст с указаниями, что исправить.
Шишка шестая, техническая. С разрастанием документации её билд начал собираться медленнее, ещё медленнее, совсем медленно. Причину искали некоторое время, но, честно говоря не особо усердно, потому что уже было ясно, что проблем у нас больше, чем выигрыша.
Шишка седьмая, основная. Согласование документации превратилось в ад.
Представьте: на согласование прилетает пачка X2 документов, ссылающихся друг на друг, но ссылки не работают; при этом схемы вы не можете посмотреть — они не отрисовываются, вы читаете файлы PlantUML и рисуете схему в голове; возможно, неправильно, потому что вы разработчик и никогда на PlantUML не писали; кроме того, вы можете видеть дельту изменений только в формате языка разметки, и пытаетесь сопоставить прочитанное и посчитанное количество палочек с не очень ровной табличкой, которую видите в предпросмотре.
А теперь представьте, что через это проходят сразу десять человек.
Чего мы только ни делали! Мы читали документацию онлайн с шарингом экрана её автором; мы кидали друг другу собранные из всей пачки документов PDF; мы выкачивали ветки эпиков, чтобы читать в IDE; мы заливали документацию без согласования, чтобы дать возможность прочитать в сносном виде с работающими ссылками.
Но все эти костыли не позволяют увидеть дельту изменений и документацию в целом единовременно.
Решение отказаться от Docs as Code было принято после того, как на согласование улетела пачка из пятидесяти документов по одному небольшому эпику. Мы планируем по-прежнему хранить документацию в репозитории, но для чтения, редактирования и согласования использовать Confluence-подобную систему. Интеграция с git была одним из критериев выбора.
Комментарии (29)
inkelyad
26.06.2024 17:07+2Соответственно если бы разработчик решил читать документацию в IDE, то первая же ссылка перебросила бы его в Hugo.
Как-то я не понял workflow. Готовое приложение никто же не смотрит в виде исходников - смотрят на какой-то экземляр, запущенный на каком-то тестовом стенде. Соответственно, документацию-как-код тоже не нужно смотреть в виде исходника тем, кто ее не пишет - все ее пользователи должны смотреть на собранный вариант конкретной ветки.
Т.е. выглядит так, что проблемы возникли в значительной степени из того, что решили 'настраивать сборку Hugo для каждой ветки эпика нецелесообразно.' Собственно, не очень понятно, в чем проблема собирать из любой ветки, какую залили в систему сборки.
Aleks_Otter Автор
26.06.2024 17:07+1Не целесообразно даже тратить ресурсы на сборку, потому что документация ветки конкретной фичи интересна примерно никому, как и исходники. Разве что для QA в момент тестирования пригодится. В остальном даже разработчики предпочитают иметь ввиду целевое решение и будущие смежные доработки.
slonopotamus
26.06.2024 17:07+2документация ветки конкретной фичи интересна примерно никому, как и исходники
Простите, а ревью?
Aleks_Otter Автор
26.06.2024 17:07Ревью при пулреквестах. У нас ревьюят лиды разработки, а не те разработчики, которые будут пилить задачу.
inkelyad
26.06.2024 17:07Не целесообразно даже тратить ресурсы на сборку, потому что документация ветки конкретной фичи интересна примерно никому, как и исходники.
Все равно не понял. Как это может выглядеть:
Вот есть некая фича на реализацию. По ней готовят документацию в какой-то ветке. Тот, кто это документацию пишет в какой-то то момент делает push исходников этой документации. Оно подхватывается pipeline сборки и заливается в каой-то стенд. И в результате разработчик смотрит на https://stand-1../docs/..../Feature-XYZ.html, пишет замеченные дефекты и замечания в бэг-трекер в сторону писателей, они их исправляют и цикл повторяется, с обновлением стендов.
А у вас как? Разработчик смотрит непосредственно в исходный код доки, пытается понять, что из него получится и пишет замечания при помощи системы Code Review прямо по исходникам документации?
Aleks_Otter Автор
26.06.2024 17:07Спасибо, поняла.
Да, при согласовании мы смотрим исходник в гитее и в предпросмотр там же. Там же пишет замечания по коду.
Собственно, идея была в том, чтобы согласовывать дельту изменений, а не итоговый вид документа...
Siddthartha
26.06.2024 17:07+2документация "сверху" (как хотят) -- в конфлюенсах и вордах, а документация "снизу" (как есть) -- в репах и маркдаун. пока так практикуем.. вроде норм.
PS: только plantUml сильно серьезно, в итоге оказалось, зато mermaid выручает быстро накидать схему, что происходит, какие-небудь sequence diagram и т.п.
SanoLitch
26.06.2024 17:07+3С вашим стеком не работал, но расскажу как решали некоторые подобные проблемы у себя:
Отображение диаграмм: мы рендерили диаграммы в png в GitHub actions.
Ссылки: вообще документы должны ссылаться на соответствующий документ в репо, а не на воображаемый в Hugo. На нашем стеке ссылки автоматически преобразовывались плагином в пайплайне при переливке в базу знаний.
То, что «сложна, непонятно и глазки болят» тут уж извините…но тот классический свинарник, который устраивают аналитики в базе знаний тоже «сложна, непонятно и глазки болят» и хрен что найдешь потом (без негатива).
Комменты по ошибкам надо оставлять на ревью в ПР, либо, если найдено пост-фактум, заводить issues в репозитории на конкретный файл и строчку и тэгать аналитика.
Про gitea ничего не знаю, но гитхаб и ide нормально отображают документы в md и asciidoc, поэтому чаще всего никакие Hugo в целом не нужны были, только для смежников (у нас была интеграция в confluence увы ныне почившая).
Поломки сборки: при создании ПРа должна проводиться автоматическая упрощенная версия сборки в ci/cd. Если не собралось - ПР блокируется.
я большой сторонник doc as a code, при нормальном ci/cd и адекватных разработчиках и аналитиках документация получается супер, хотя конечно не панацея и испортить можно все что угодно.
В противовес был у меня проектик где дока хранилась и в репо, и в Миро, и в базе знаний, и в тикетах, чатах и бог знает где еще. Разумеется актуальной она была нигде. Вот это ад.
Spiritschaser
Ясно, понятно:
Спасибо, gitlab и confluence тогда отлично подходят - оба поддерживают asciidoc
Aleks_Otter Автор
Так и наши поддерживают) На эстетические грабли мы наступили далеко не сразу. Нюансы отображения иногда способны очень сильно испортить читаемость, пока не наткнёшься -- не узнаешь о них (