Единый источник и CI-CD для Gostdown
Gostdown - замечательный проект для нас, несчастных, крепко завязанных на Microsoft Word. И все же в основной версии кое-чего важного ему не хватает: трушного single source, переменных и CI/CD. Но нет ничего невозможного для ленивого техписа, который хочет, чтобы оно все само!
Single Source и CI/CD для Gostdown
Мой первоначальный фреймворк описан в двух предыдущих постах (DocOps из костылей и палок и Проверка орфографии с LanguageTool и Vale). Для этого поста я также подготовила демонстрационный репозиторий demo-gostdown-plus. Эту версия успешно отработала на последней версии pandoc (3.1) и pandoc-crossref (v0.3.15.1).
В репозитории есть README, в котором описан быстрый старт проекта. В этом посте я опишу новые фичи чуть подробнее, а также расскажу, как прикрутить к проекту CI/CD на GitLab.
В чем отличия от основной версии:
- Можно использовать один шаблон для всех документов: прикручен скрипт update_docx_props. Теперь в конфигах для каждого документа можно задавать его название, децимальные номера и вообще любые поля.
- Команда запуска pandoc в скрипте
build.ps1
Gostdown модифицирована. Теперь можно использовать фильтры pandoc. Добавлены фильтры для включения файлов (include_files.lua
) и обработки переменных (metadata_processor.lua
). Single-source рулит! - Прикручена возможность собирать простой одностраничный HTML простым pandoc.
- Отлажены Tasks для VSCode. Таски позволяют запускать скрипты без всяких bat-ников, что уменьшает дублирование. Один скрипт
build.ps1
для билда доков rules them all. - Прикручена проверка правописания с Vale. Эта очень полезная штука просто спасает мне жизнь при переносе информации с внутренней вики, отлично отлавливает сленг.
- Чтобы любой чайник мог собрать документ прямо в GitLab, прикручен CI/CD (CI/CD конфигурация из репозитория Gostdown у меня не заработала).
Проехали.
Обновление свойств документа
В Gostdown для формирования документа docx используется шаблон, в котором задается титул, название документа, децимальный номер и прочие общие сведения. Если документов в проекте много, то держать в репозитории несколько шаблонов расточительно, особенно, если отличаются они только названием и децимальными номерами.
К счастью, у меня уже есть скрипт для обновления полей документов update_docx_props. Понадобилась лишь доработка напильником, чтобы можно было вызывать скрипт для одного файла (эта версия лежит вот тут, рядышком).
Получается вот такой workflow:
- Собрать документ. Документ сохранен в директорию
/build
(настраивается в таске). - Запустить таску «Update docx fields». Выбрать из списка документ (документ соответствует названию файла и директории).
- Скрипт обновления свойств будет запущен для выбранного документа.
Настройка:
- Создать в директории проекта папку
/build
. - В папку
scripts
сохранить скриптupdate_docx_props.ps1
. -
В папке
scripts/configs
создать конфигурационный файл для документа с таким же именем, как папка документа (все это конечно же можно модифицировать в скрипте или таске). В конфигурационном файле указать свойства, которые нужно обновлять.<?xml version="1.0"?> <configuration> <customProperties> <add key="DeviceName" value="Красивое название"/> <add key="DocTitle" value="Описание программы"/> <add key="DecimalNumber" value="АБВГ.00002 01 13"/> <add key="DocSubtitle" value="Подзаголовок"/> <add key="DocYear" value="2023"/> </customProperties> <builtinProperties> <add key="Title" value="Красивое название. Описание программы"/> <add key="Subject" value="Красивое название"/> <add key="Keywords" value="description"/> <add key="Comments" value="2023"/> </builtinProperties> <vsdProperties> </vsdProperties> </configuration>
-
Создать таску для VS Code в
.vscode/tasks.json
:{ "label": "Update docx fields", "detail": "Update builded document", "type": "shell", "options": { "cwd": "${workspaceFolder}/build/" }, "command": "${workspaceFolder}\\scripts\\update_docx_props.ps1 -dir ${workspaceFolder}\\build -conf ${workspaceFolder}\\scripts\\configs\\${input:doc}.xml -filename ${input:doc}.docx", "presentation": { "echo": true, "reveal": "always", "focus": false, "panel": "shared", "showReuseMessage": false, "clear": true } }
-
В таске используется input variables. Их удобно использовать, например, для запуска одной таски для нескольких директорий:
"inputs": [ { "id": "doc", "description": "Document Path: ", "type": "pickString", "options": [ "example_doc", "another_doc" ], "default": "example_doc" }, ]
Все, теперь при запуске этой таске, собранный документ в build
будет обработан, название, год, децимальный номер обновлен.
Добавляем single-source и переменные
В общем я не думала, что мне опять понадобиться single-source, но жизнь требования технического задания распорядились иначе. 9 комплектов документов с большими общими кусками, кусками, отличающимися только названием ПО - без single source тут с ума сойдешь.
Вот как это работает:
- Файлы с общими кусками текста лежат где-то в общей папке. В демонстрационном репозитории это
docs_gost/single_source
. - В файле или файлах основного документа (например, в
docs_gost/example_doc
) вставляем в нужные места файлы изdocs_gost/single_source
специальным синтаксисом. - В шапке документа (в YAML-преамбуле) добавляем свои переменные (например, в
docs_gost/single_source/00_begin.md
добавлена переменнаяsoft-name
). - В тексте к переменной обращаемся вот так:
${soft-name}
. При сборке сюда будет подставлено значение переменной из преамбулы. - Модифицированная команда pandoc в
build.ps1
применяет все необходимые фильтры и обрабатывает результат. А затем передает уже основному скриптуbuild.ps1
, который применяет шаблон и творит свою COMKbject-овскую магию.
В демонстрационном репозитории example_doc
имеет все перечисленные фичи: переменную, включенные файлы и разнообразные картинки. И да, в файлах-источниках (который в single_source
) тоже можно использовать переменные, они будут заменены на значение из основного файла.
К счастью, добрые люди уже разработали все необходимые фильтры, так что их осталось просто немного доработать.
Стандартный фильтр из репозитория pandoc include-files уже делает все, что нужно для счастья. В документе, в который хотим что-то вставить пишем (см. пример):
В команде pandoc передаем ключ -M include-auto
, если нужно автоматически перенумеровывать заголовки. Также можно для каждого блока указывать свои правила нумерации. Я пока обхожусь -M include-auto
.
Для переменных тоже уже написано немало фильтров. Я адаптировала вот этот pandoc-curly-switch.
Минусы использования этих фильтров – не полная совместимость с mkdocs, с которой я пока не разбиралась. В mkdocs тоже есть переменные и плагин include, так что вероятно их можно совместить с pandoc-фильтрами.
Команда pandoc с нашими фильтрами для теста:
pandoc (cat *.md) -o some.docx -M include-auto --lua-filter include_files.lua --lua-filter linebreaks.lua --lua-filter metadata_processor.lua --filter pandoc-crossref --citeproc --reference-doc template.docx
А вот команда вызова pandoc в скрипте Gostdown. Как видно добавлена переменная $luafilter
, в которой передается путь к папке с фильтрами .lua
.
&$exe $md -o $tempdocx -M include-auto --lua-filter $luafilter\include_files.lua --lua-filter $luafilter\linebreaks.lua --lua-filter $luafilter\metadata_processor.lua --filter pandoc-crossref --citeproc --reference-doc $template
Одностраничный HTML по шаблону
mkdocs крут, но не всегда нужен полноценный сайт с документацией. Иногда нужен просто одностраничный HTML с навигацией, чтобы быстро отправлять инженерам по запросу.
К счастью здесь ничего сложного придумывать не надо, так как pandoc уже все умеет, нужно только подобрать правильное заклинание команду.
Шаблон для pandoc можно взять готовый, я использую easy-pandoc-templates by ryangrose. Их легко можно адаптировать для своих нужд, скачать все необходимые ресурсы, чтобы шаблоны работали оффлайн.
Команда для конвертации кучки .md файлов в HTML:
pandoc -s $(Get-Content html_include.txt) -f markdown --quiet --template=easy-template.html --lua-filter=include_files.lua --lua-filter=linebreaks.lua --lua-filter=metadata_processor.lua --filter pandoc-crossref --citeproc -o output.html --toc
В файле html_include.txt
на каждой строке перечислены все md файлы, которые хотим слепить в одностраничный HTML. В скрипте create_simple_html.ps1
эта команда параметризована, так что можно легко вызывать скрипт в тасках VSCode.
В таске VSCode команда для вызова получилась развесистая, так как помимо сборки документа, нужно также скопировать все картинки. Это делается автоматически таской.
К сожалению, из таски не получится вызвать команду замены путей к картинкам напрямую, поэтому пришлось запихать её в скрипт command_to_fix_image_paths.ps1
и в таску Fix img path in HTML
. Таска проходится по всем .html в папке build/web
и заменяет пути к картинкам. Вот, теперь у нас красивый, рабочий HTML.
Таски
Я уже немного писала про таски для запуска стандартных батников Gostdown. Но в тасках можно вызывать скрипт build.ps1
напрямую и передавать ему все необходимые параметры. Это позволило убрать из проекта дублирующиеся скрипты и bat, и создать одну единственную задачу для сборки всех документов.
Рассмотрим вот такую таску из демонстрационного проекта:
{
"label": "Build Doc",
"detail": "Build selected in docx_include.txt to build docs",
"type": "shell",
"options": {
"cwd": "${workspaceFolder}/docs_gost/${input:doc}/"
},
"command": "${workspaceFolder}\\scripts\\build.ps1 -md $(Get-Content docx_include.txt) -template ${workspaceFolder}\\docs_gost\\template.docx -luafilter ${workspaceFolder}\\scripts -docx ${workspaceFolder}\\build\\${input:doc}.docx -embedfonts",
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "shared",
"showReuseMessage": false,
"clear": true
},
"group": {
"kind": "build",
"isDefault": false
}
}
Как видно, это просто команда из build.bat
скрипта Gostdown. Добавлен параметр -luafilter
, в котором указан путь к фильтрам pandoc. Кроме того, обратите внимание, чтобы отработали правильно все скрипты, рабочая директория должна быть установлена в корне собираемого документа (параметр options.cwd
).
Список файлов .md, которые нужно собрать, теперь лежат в файле docx_include.txt
в корне документа.
В таске используются переменные input variables, о которых уже говорилось выше. Таким образом, эту таску можно запускать для всех документов: при запуске пользователю будет предложено выбрать документ для сборки.
Прикручиваем CI/CD на GitLab
Итак, наконец-то я добралась до уровня с боссом CI/CD. Пришлось просмотреть немало всяких прохождений, но я справилась😊. Теперь в репозитории проекта любой менеджер или разработчик может собрать себе docx и скачать артефакты. И теперь техпису не нужно таскать с собой в отпуск ноутбук!
Gitlab’овский CI/CD состоит из двух важных компонентов и двух конфигов:
- gitlab-runner нужно установить на машину с Windows, на которой будет выполнена сборка. Эта служба выполняет все нужные команды для сборки нашего проекта;
- в проекте на сайте Gitlab должна быть включена функция CI/CD;
- в корне проекта должен существовать файл
.gitlab-ci.yml
с описанием порядка сборки (команды). Все это будет передано gitlab-runner’у на исполнение; - рядом с исполняемым файлом gitlab-runner должен лежать конфиг
config.toml
, в котором описаны настройки подключения к Gitlab.
Все нижеописанные непотребства я проделывала на selfhosted Gitlab/Gitlab runner версии 15.8, Windows 10, Microsoft Word 2021. Предполагается, что у вас есть права владельца проекта на Gitlab’е и возможно установить политику запуска PowerShell скриптов в Unrestricted
и RemoteSigned
.
Кроме того, на машине, которую будете использовать для сборки, должен быть установлен весь набор программ: Git, pandoc/pandoc-crossref, Microsoft Word, шрифты. Рекомендую также поставить расширение Gitlab Workflow для VSCode для валидации конфигов и запуска пайплайнов прямо из VSCode.
Установка и настройка gitlab-runner
В официальной документации присутствует туториал по установке и настройке gitlab-runner, однако прямо скажу, не очень он отражает суровую действительность и количество проблем, с которыми пришлось столкнуться.
- Для начала активируем для проекта CI/СD (Settings -> General -> Visibility, project features, permissions -> Expand -> включить CI/CD).
- В разделе Setting -> CI/CD -> Runners (Expand) есть информация, которую нужно указывать при регистрации gitlab-runner ниже (token и адрес). Если у вас selfhosted Gitlab на докерах, то адрес может быть с HTTP, даже если у вас HTTPS. Если при регистрации gitlab-runner появляется ошибка 401, то вам нужен HTTPS.
- Делаем по туториалу Install Gitlab Runner on Windows, ну по крайней мере первые пункты совпадают ). На машине создаем папку без кириллицы (
D:\gitlab-runner
). Нужен раннер на каждый проект (или ваш Администратор может настроить групповой раннер). - Положить туда .exe, (вот файл). Переименовать exe в
gitlab-runner.exe
(для удобства, можно как угодно назвать). - Если у вас self-signed сертификат в Gitlab’e, экспортируйте его с сайта и положите в рабочую папку раннером (например, файл
gitlab.blabla.ru.crt
). - Запустить от администратора консоль (обычную, не powershell) и перейти в папку с раннером (
d:
,cd D:\D:\gitlab-runner
). -
Выполнить в консоли следующую команду. В
TOKEN
надо указать токен проекта со страницы Setting -> CI/CD -> Runners (Expand), а вtls-ca-file
– абсолютный путь к сертификату. Вexecutor
можно указать несколько оболочек (https://docs.gitlab.com/runner/executors/), мне нужен только shell:gitlab-runner register --non-interactive --registration-token TOKEN --url https://gitlab.blabla.ru/ --tls-ca-file D:\gitlab-runner\gitlab.blabla.ru.crt --executor shell
- Раннер будет зарегистрирован и появится на странице Setting -> CI/CD -> Runners (Expand).
- Открыть конфигурационный файл
config.toml
(появится рядом с exe раннера после регистрации) и поменятьpwsh
в ключеshell
наpowershell
(иначе при запуске пайплайна будет ошибка, что путь не найден). - Установить службу командой
gitlab-runner.exe install
и запуститьgitlab-runner.exe start
. Если вы измените конфигconfig.toml
, то службу нужно перезапустить. - После этого на странице Setting -> CI/CD -> Runners раннер должен стать зелененьким. Если не стал, значит что-то не так, и джобы не запустятся.
- В “Службах” в Windows перейти в свойства службы gitlab-runner -> Вход в систему > галка “Разрешить взаимодействие с рабочим столом”.
В общем все готово, и можно выполнить тестовую джобу из туториала. Для этого нужно скопировать содержимое тестового примера в файл .gitlab-ci.yml
в корне проекта и закоммитить. В данном случае джоба будет запущена автоматически, сразу после коммита, и появится в разделе CI/CD -> Jobs. В консоли будут выведены команды echo
.
Что делает джоба? Выкачивает с помощью Git наш проект из репозитория и применяет перечисленный в .gitlab-ci.yml
команды. Артефакты, которые получились в результате, пакует и передает Gitlab’у. Артефакты можно скачать в результатах работы или с вкладки Release (если она была настроена).
Ошибки раннера можно смотреть в Windows в Просмотре Событий или в powershell Get-WinEvent -ProviderName gitlab-runner
.
Исправляем ошибки и фиксим конфиги
Как вы понимаете, если бы все было так просто, мы бы тут не собирались. Первая проблема, с которой я столкнулась – кракозябры в консоли на GitLab. Потом отказывался запускаться скрипт. Потом скрипт не мог найти нужные пути. Короче, без долгих прелюдий перехожу сразу к списку фиксов возможных проблем.
Кракозябры в консоли на GitLab
Чтобы gitlab-runner не писал кракозябры в скрипт .gitlab-ci.yml
в конфиг работы нужно добавить CHCP 65001
:
build-job:
before_script:
- CHCP 65001
stage: build
script:
Это еще не все. На машине, на которой стоит gitlab-runner нужно переключить региональные настройки на Английский (США): Региональные параметры -> Дополнительные параметры … _ -> _Региональные стандарты - Изменение форматов даты, времени и чисел _ -> _Дополнительно -> Изменить язык системы -> выбрать Английский (США).
Это тоже еще не все, так как при запуске скриптов build.ps1
и update_docx_props.ps1
могут возникнуть проблемы с кодировкой. Эти скрипты нужно открыть в блокноте Notepad++ и пересохранить в кодировку UTF-8 BOM
. В демонстрационном репозитории все уже в правильной кодировке.
Если переключение региона - не вариант
Вариант с региональными настройками не удобен, если нужно работать с non-unicode программами, например, макросами Microsoft Word в VBA. В этом случае, макросы поиска кириллицы работать не будут. Можно конечно переводить каждый символ ChrW
, но это работает еще хуже. Сделать можно так:
- Переключаем региональные настройки обратно на Русский (Россия).
-
Проверяем, есть ли у нас профиль для консоли PowerShell. Если профиля нет, то создаем его:
$profile test-path $profile new-item -path $profile -itemtype file -force
- Добавляем в файл строку
$OutputEncoding = [console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding
(source) - Или то же самое программно, через консоль:
'$OutputEncoding = [console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding' + [Environment]::Newline + (Get-Content -Raw $PROFILE -ErrorAction SilentlyContinue) | Set-Content -Encoding utf8 $PROFILE
Готово! Работает это не так красиво, как с настройкой региона, но хотя бы теперь можно использовать макросы и кракозябр в консоли поменьше.
Git, пути и директории
Если вы, как я, до этого никогда не имели дела с настройкой CI/CD (кроме как GitHub, который все сам делает), то можно зависнуть на очень простых ошибках.
Иногда, при скачивании с Git работа может упасть с ошибкой авторизации (Authentication error). Это происходит рандомно у разных людей. Чтобы исправить ошибку, нужно в конфигурационный файл gitlab-runner config.toml
под параметром url
добавить еще одну строку с параметром clone_url
. URL указать точно такой же как в url
. Магия, что сказать.
Чтобы запускать наши скрипты, нам полезно будет иметь фиксированные директории. По умолчанию gitlab-runner скачивает репозиторий в папку с названием из рандомного набора букв и цифр (например, build/123hjksd898231
).
В конфиг config.toml
в раздел [runners.custom_build_dir]
добавить строчку enabled = true
.
Вот как примерно выглядит конфиг после всех фиксов:
concurrent = 1
check_interval = 0
shutdown_timeout = 0
[session_server]
session_timeout = 1800
[[runners]]
name = "docbuilder"
url = "https://gitlab.blabla.ru/"
clone_url = "https://gitlab.blabla.ru/"
id = 6
token = "SOMETOKEN"
token_obtained_at = 2023-02-16T11:50:04Z
token_expires_at = 0001-01-01T00:00:00Z
tls-ca-file = "D:\\gitlab-runner\\gitlab.blabla.ru.crt"
executor = "shell"
shell = "powershell"
[runners.custom_build_dir]
enabled = true
[runners.cache]
MaxUploadedArchiveSize = 0
[runners.cache.s3]
[runners.cache.gcs]
[runners.cache.azure]
Эта настройка позволит в конфигурации .gitlab-ci.yml
задавать путь, куда будет склонирован проект:
variables:
GIT_CLONE_PATH: $CI_BUILDS_DIR/$CI_PROJECT_NAME
Код будет склонирован в папку /build/[название проекта с Gitlab]
. Можно также указать вместо $CI_PROJECT_NAME
любое имя.
Когда будете формировать шаги по сборке gostdown’ом очень рекомендую использовать команды перехода по директориям перед выполнением скриптов.
Скрипты не будут выполнятся, если их путь начинается с переменной (./$CI_BUILDS_DIR/test/build.ps1
будет ругаться на You must provide a value expression following the '/' operator.
, Unexpected token
, Missing closing '}' in statement block or type definition
и все подряд).
Кроме того, скрипт build.ps1
необходимо запускать из директории документа, который вы собираете. В противном случае, pandoc сначала не найдет файлов, потом не найдет include, потом вообще обидится и упадет с ошибкой. Так что если что-то не собирается, и возникают непонятные ошибки, сначала проверьте все пути!
Права, разрешения и доступ к COMObject
Если вы сразу после установки и успешного выполнения джобы из туториала попробуете запустить скрипт Gostdown, то ничего у вас не выйдет. Скрипт свалится вот на этой строчке: $word = New-Object -ComObject Word.Application
.
Нет, у меня сначала все получилось, потому что я запускала все на своем ноутбуке для тестирования. Но при переносе пайплайна на отдельный сервер вылезли ошибки, связанные с правами запуска службы и разрешениями COMObject.
Такая горемыка была не я одна, про это есть тред на stackoverflow. В одиноком ответе к этой проблеме содержится способ решения (завела для этого аккаунт на stackoverflow :).
- В “Службах” найти gitlab-runner -> Свойства на вкладке Вход в систему поставить переключатель в С учетной записью и указать имя пользователя и пароль (я указала пользователя с административными правами, под которым ставила pandoc, word и все остальное).
- Выберите Пуск -> Выполнить (или нажмите Win + R) -> введите
MMC -32
и нажмите ОК. - Выберите Файл -> Добавить/удалить оснастку ->_ добавьте Службы компонентов_. Сохраните консоль.
- Запустите сохраненную консоль с правами администратора.
- Раскройте дерево Службы компонентов до Мой компьютер и выберите Настройка DCOM.
- Найдите
Microsoft Word 97 - 2003 Document
-> ПКМ -> _Свойства. - На вкладке Удостоверение выберите Указанный пользователь и укажите учетные данные пользователя (такой же как на шаге 1).
- На вкладке Безопасность > Разрешения на доступ выбрать Настроить и добавить явно своего пользователя и выдать ему все разрешения. Также у меня выданы разрешения в разделе Разрешения на настройку. Это риск безопасности, так что выполняйте такую настройку только в доверенной сети.
Вот, теперь должно работать. Имейте в виду, что теперь работа не будет запускаться, если выполнен интерактивный вход под тем же пользователем (то есть вы залогинены, например, по удаленному рабочему столу). Для тестирования можно переключить в пункте 7 удостоверение на интерактивного пользователя, тогда служба будет запускаться с правами залогиненного пользователя.
Еще несколько моментов:
- Если работа зависла на этапе взаимодействия с Word, то все дальнейшие запуски и работы завершаться ошибкой, так как процесс Word будет продолжать висеть. Чтобы этого не происходило, можно добавлять в конфиг работы команду
Stop-Process -Name "WINWORD"
перед или после выполнения скрипта (лучше до). - Если работа завершилась ошибкой, на этапе взаимодействия с
template.docx
, то следующее открытие Word может повиснуть с диалоговым окном, которое нужно закрыть вручную. Как это обойти, я пока не поняла, но больше работы у меня не зависали, так что это редкая ошибка.
Пример конфига
Так как в демонстрационном проекте на GitHub показать сборку затруднительно, я покажу рабочий конфиг работы и вывод консоли.
Ниже конфиг .gitlab-ci.yml
для сборки одного документа (в данном случае - программа и методика испытаний, её чаще всего требуется собирать). Работа собирает документ, обновляет поля и отправляет артефакты работы в Gitlab.
Keyword workflow
обрабатывается перед работами и определяет, будет ли генерироваться пайплайн и при каких условиях (см. документацию). В данном случае, пайплайн будет сгенерирован только, если в commit message содержится ключевой флаг -build
.
variables:
GIT_CLONE_PATH: $CI_BUILDS_DIR/$CI_PROJECT_NAME
workflow:
rules:
- if: $CI_COMMIT_MESSAGE =~ /-build$/
Build PMI:
before_script:
- CHCP 65001
stage: build
when: manual
script:
- echo "Starting building PMI..."
- mkdir build
- echo "Reading include file..."
- get-content $CI_BUILDS_DIR/$CI_PROJECT_NAME/docs_gost/pmi/docx_include.txt | foreach {"builds/$CI_PROJECT_NAME/docs_gost/pmi/" + $_} | out-file $CI_BUILDS_DIR/$CI_PROJECT_NAME/docs_gost/pmi/include.txt
- echo "Building..."
- cd $CI_BUILDS_DIR/$CI_PROJECT_NAME/docs_gost/pmi
- ./../../scripts/build.ps1 -md $(Get-Content $CI_BUILDS_DIR/$CI_PROJECT_NAME/docs_gost/pmi/include.txt) -template $CI_BUILDS_DIR/$CI_PROJECT_NAME/docs_gost/template.docx -luafilter $CI_BUILDS_DIR/$CI_PROJECT_NAME/scripts/ -docx $CI_BUILDS_DIR/$CI_PROJECT_NAME/build/pmi.docx -embedfonts
- sleep 5
- echo "Updating fields..."
- cd $CI_BUILDS_DIR/$CI_PROJECT_NAME
- ./scripts/update_docx_props.ps1 -dir $CI_BUILDS_DIR/$CI_PROJECT_NAME/build -conf $CI_BUILDS_DIR/$CI_PROJECT_NAME/scripts/configs/pmi.xml -filename pmi.docx
- sleep 5
artifacts:
paths:
- build/pmi.docx
expire_in: 1 hour
Параметр expire_in
устанавливает время хранения собранного документа на Gitlab. По истечение этого срока, артефакт удаляется. Однако, по умолчанию GitLab в версии, начиная с 13, всегда сохраняет последний артефакт (это настраивается для каждого проекта в секции CI/CD).
Если нужно, чтобы работа запускалась автоматически только для мастера, а для всех остальных веток – только вручную, то в работу (или в workflow
) можно добавить правило (пример):
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
when: always
- if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
when: manual
Также можно сделать, чтобы пайплайн и работа формировались только при наличии в коммите ключевого слова. Например, у меня настроено так, что пайплайн формируется только при коммите с ключевым словом [build]
, работу можно запустить вручную. А если нужно собрать автоматически (например, конкретный документ), то в коммите также передаем флаг с документом:
workflow:
rules:
- if: $CI_COMMIT_MESSAGE =~ /\[build\]/
Build PMI:
before_script:
- CHCP 65001
stage: build
rules:
- if: $CI_COMMIT_MESSAGE =~ /\[pmi\]/
when: always
- if: $CI_COMMIT_MESSAGE !~ /\[pmi\]/
when: manual
В шаге скрипта Reading include file...
выше выполняется операция по изменению путей в файле docx_include.txt
. По умолчанию в этом файле хранится список .md, которые мы хотим включить в результирующий .docx. Однако при запуске gitlab-runner пути в этом файле нужно изменить на относительные пути от gitlab-runner.exe, что и сделано в этом шаге.
На рисунке ниже видно, что отработал скрипт обновления полей документов: вопросительные знаки вместо русского языка из-за региональных настроек, в документе все будет установлено корректно.
Чистим историю пайплайнов
Пока я тестировала ci/cd, в проектах образовалась длинная история работ и пайплайнов. Вручную их удалять очень долго, а кнопки “почистить историю” в гитлаб еще не завезли.
Поэтому рекомендую проводить тесты и настройку на тестовом проекте, который не жалко будет грохнуть.
Если же вас, как и меня, бесит грязная история failed
пайплайнов, то можно почистить историю скриптом на Python с библиотекой python-gitlab:
import gitlab
project_id = 55
gl = gitlab.Gitlab('https://gitlab.blabla.ru/', private_token='TOKEN', api_version='4',ssl_verify=False)
project = gl.projects.get(project_id, obey_rate_limit=False)
for pipeline in project.pipelines.list(as_list=False):
pipeline.delete()
Если у вас selfhosted GitLab, то возможно придется немного доработать скрипт в зависимости от вашего SSL, мне хватило просто отключить проверку. В скрипте нужно указать ID проекта, URL и токен. Запустить скрипт 2-3 раза - и ура, история пайплайнов чиста и прекрасна, и позорные ошибки никто не увидит )
Вместо эпилога
Полагаю, после всех пережитых приключений логичным следующим этапом должно быть прикручивание какого-нибудь ChatGPT или аналогичной сетки к документации. А то что, у нас зря что ли отдел машинного обучения сидит, ерундой важными проектами занимается?
Уже есть интересные плагины для редактора ObsidianMD и в облачном Notion, которые делают неплохие summary - для научных отчетов и обзоров литературы просто огонь. Также есть немало задач, где требуется набросать несложную инструкцию по официальной документации (например, docker, linux и т.д.).
Как вы поняли, конечная цель, чтобы документация писалась сама, я потеряла работу и ушла работать дворником. Их вроде не собираются автоматизировать, здесь пока люди дешевле технологий.