1С без конфигуратора: полный цикл разработки расширения из командной строки

24.08.26

Разработка - DevOps и автоматизация разработки

Полный цикл разработки расширения 1С в пакетном режиме DESIGNER: выгрузка, правка, гейт компиляции, применение к базе и контроль результата — без единого клика в конфигураторе. Разбираю семь мин, на которых подорвался лично: почему LoadConfigFromFiles возвращает нулевой код на битом модуле, зачем нужен Xvfb, как pgrep находит сам себя, кто держит базу и как отличить работающий сеанс от забытого, и почему после рестарта сервера база остаётся закрытой. Платформа 8.3.27, УТ 11.5, сервер на Linux.

О чём это

Год назад у меня была задача: править расширения боевой УТ 11.5 с ноутбука, находясь в другом часовом поясе от сервера, и делать это так, чтобы кассы не вставали. Конфигуратор — приложение с графическим интерфейсом, RDP до сервера был медленным, а любая ошибка стоила простоя магазинов.

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

Главная из них: штатная команда загрузки конфигурации не компилирует код и возвращает нулевой код возврата на заведомо битом модуле. Если строить пайплайн наивно, вы будете уверены, что выкатили рабочий код, пока не позвонит кассир.

Статья описывает рабочий цикл целиком, с проверками, которые действительно ловят ошибки. Платформа 8.3.27, конфигурация УТ 11.5, сервер на Linux. Для Windows команды те же, отличается только обвязка.


Команды, из которых складывается цикл

Задача Команда
Выгрузить расширение в файлы DESIGNER /DumpConfigToFiles <dir> -Extension <имя>
Загрузить расширение из файлов DESIGNER /LoadConfigFromFiles <dir> -Extension <имя>
Применить изменения к базе DESIGNER /UpdateDBCfg -Extension <имя>
Проверить компиляцию DESIGNER /CheckModules -Extension <имя> -Server
Выгрузить внешнюю обработку в файлы DESIGNER /DumpExternalDataProcessorOrReportToFiles <dir> <file.epf>
Собрать обработку из файлов DESIGNER /LoadExternalDataProcessorOrReportFromFiles <root.xml> <out.epf>

Ключ -AllExtensions вместо конкретного имени выгружает все расширения разом, каждое в подкаталог <dir>/<имя расширения>. Удобно, когда нужно снять слепок состояния базы целиком.

При выгрузке внешней обработки корневой XML пишется рядом с каталогом, а не внутрь него: указали /tmp/proc — получите каталог /tmp/proc и файл /tmp/proc.xml. Это неочевидно и ломает наивные скрипты, которые ожидают всё в одной папке.


Мина первая: загрузка не значит компиляция

Наивный пайплайн выглядит так: выгрузили, поправили Module.bsl, загрузили обратно, применили к базе. Проверять вроде нечего — команды отработали, коды возврата нулевые.

Проблема в том, что /LoadConfigFromFiles не компилирует модули. Она разбирает XML-структуру и складывает тексты модулей в конфигурацию как есть. Если в модуле синтаксическая ошибка — незакрытая скобка, опечатка в имени процедуры, лишняя точка с запятой — команда завершится с кодом 0 и напишет в лог, что всё хорошо.

Ошибка всплывёт позже: при /UpdateDBCfg, либо вообще в момент первого обращения пользователя к этому коду. То есть на кассе.

Единственная настоящая проверка — /CheckModules:

DESIGNER /CheckModules -Extension <имя> -Server

Она реально компилирует модули на стороне сервера и выдаёт ошибки с номерами строк и именами модулей. Занимает около минуты на среднее расширение. Это дорого для цикла «поправил-проверил», но абсолютно обязательно перед применением к бою.

Ключ -Server важен: без него проверяются не все контексты выполнения, и часть ошибок в серверных процедурах пройдёт мимо.

Правило, к которому я пришёл: между /LoadConfigFromFiles и /UpdateDBCfg всегда стоит /CheckModules, и пайплайн останавливается, если она вернула ошибки. Без этого гейта автоматизация опаснее ручного конфигуратора — тот хотя бы подсвечивает синтаксис при сохранении.


Мина вторая: без Xvfb ничего не запустится

На Linux-сервере без графической подсистемы любая команда DESIGNER падает с сообщением:

Unable to initialize GTK+

Платформа тянет за собой GTK даже в пакетном режиме, где никакого интерфейса нет и не предполагается. Лечится виртуальным X-сервером:

xvfb-run -a 1cv8 DESIGNER /S <сервер>\<база> /N <пользователь> /P <пароль> \
  /DumpConfigToFiles /tmp/cfg -Extension <имя>

Ключ -a заставляет xvfb-run самому выбрать свободный номер дисплея — без него параллельные запуски дерутся за :99 и падают.

Отсюда же вытекает следующая проблема.


Мина третья: модальные диалоги вешают процесс молча

Раз есть виртуальный экран, значит на нём могут появляться окна. И они появляются.

Самый частый случай — «Предупреждение безопасности» при первом открытии внешней обработки. В обычном конфигураторе вы нажимаете «Да» и забываете. В Xvfb окно висит на невидимом экране, процесс ждёт ответа, а вы наблюдаете команду, которая «выполняется» третий час без единой строчки в логе.

Диагностика неприятная, потому что дисплеев в системе бывает несколько, и окно живёт только на одном из них:

for A in $(pgrep -a Xvfb | grep -oE "/tmp/xvfb-run[^ ]*/Xauthority"); do
  D=$(pgrep -a Xvfb | grep "$A" | grep -oE ":[0-9]+" | head -1)
  echo "$D -> $(XAUTHORITY=$A DISPLAY=$D xwininfo -root -tree 2>/dev/null | grep -c 1cv8)"
done

Цикл пробегает по всем живым Xvfb и печатает, на каком дисплее сколько окон платформы. Дальше можно посмотреть, что там:

XAUTHORITY=<auth> DISPLAY=:NNN import -window root /tmp/screen.png

И даже нажать кнопку, если очень нужно:

XAUTHORITY=<auth> DISPLAY=:NNN xdotool mousemove 967 484 click 1

Способ работающий, но это лечение симптома. Правильный вывод: в автоматизированном цикле не должно быть операций, способных открыть модальное окно. Если такая операция появилась — её надо убирать из пайплайна, а не учиться кликать вслепую.


Мина четвёртая: обрыв ssh убивает конфигуратор на середине

/UpdateDBCfg на большой конфигурации идёт минутами. Если запустить её обычной ssh-командой и потерять связь, процесс получит SIGHUP и умрёт посреди применения изменений к базе данных. Состояние после такого — отдельное приключение.

Запускать долгие команды нужно так, чтобы они пережили обрыв:

setsid nohup xvfb-run -a 1cv8 DESIGNER ... </dev/null >/tmp/upd.log 2>&1 &

setsid выносит процесс в отдельную сессию, nohup глушит SIGHUP, </dev/null отвязывает stdin — без него процесс может получить SIGTTIN при попытке чтения с закрытого терминала.

И отдельное правило: не плодить параллельные запуски. Два DESIGNER на одну базу начнут драться за блокировку конфигурации, и в лучшем случае один упадёт, в худшем — оба повиснут. Перед запуском стоит убедиться, что предыдущий завершился.

Причём убедиться внимательно.


Мина пятая: pgrep находит сам себя

Естественная проверка «конфигуратор ещё работает?» выглядит так:

pgrep -f "1cv8 DESIGNER"

Если запустить её внутри цикла ожидания, который сам был вызван как bash -c '... 1cv8 DESIGNER ...', то pgrep найдёт собственную ssh-команду: строка с этим текстом присутствует в командной строке обёртки.

Результат — вечный цикл ожидания процесса, который завершился полчаса назад. Я потерял на этом ровно столько.

Лечится матчингом по полному пути бинарника:

pgrep -af "x86_64/8.3.27.1688/1cv8 DESIGNER"

и обязательной проверкой вывода глазами, а не только кодом возврата.


Кто держит базу: диагностика через ras/rac

Рано или поздно DESIGNER упадёт с сообщением «Ошибка блокировки информационной базы для конфигурирования». Значит, кто-то держит конфигуратор открытым.

В логе /Out видно, чей это сеанс: имя компьютера, номер сеанса, время начала. Но дальше начинается интересное — надо понять, там работают или человек ушёл домой, забыв закрыть окно. В первом случае надо ждать, во втором — снимать.

Сначала поднимаем администрирование кластера. ras по умолчанию не запущен, поэтому rac отвечает «Connection refused»:

setsid nohup ras cluster --port=1545 localhost:1540 </dev/null >/dev/null 2>&1 &

Дальше смотрим сеанс:

rac session info --session=<uuid> --cluster=<uuid> localhost:1545

Как читать вывод — самое важное во всём разделе:

  • calls-last-5min, cpu-time-last-5min, duration-last-5min, bytes-last-5min равны нулю → сеанс висит, в нём никто не работает;
  • last-active-at тикает даже у забытого окна, потому что клиент периодически пингует сервер. По этому полю судить об активности нельзя, и это ловушка, в которую попадают почти все;
  • суммарные duration-all и cpu-time-total в сотни миллисекунд за несколько часов означают, что человек поработал минуту и ушёл.

Забытый сеанс снимается:

rac session terminate --session=<uuid> --cluster=<uuid> localhost:1545

Отдельно стоит проверить, не ваш ли это собственный зависший DESIGNER из прошлого запуска — по моему опыту, виновником чаще всего оказывается именно он.


Мина шестая: после рестарта сервера умирает ras

Скрипты применения обычно закрывают базу от пользователей на время работ и открывают обратно:

rac infobase update --sessions-deny=on  ...   # закрыли
# ... работы ...
rac infobase update --sessions-deny=off ...   # открыли

Если между этими шагами случился systemctl restart srv1cv8 — а он случается, например при смене параметров кластера — то ras умирает вместе с сервером. Команда снятия блокировки молча не выполняется, база остаётся закрытой, а HTTP-сервисы начинают отдавать 500.

Со стороны это выглядит как «мы всё сделали правильно, а приложение легло».

Вывод простой: финальное состояние проверять фактом, а не кодом возврата скрипта. Две проверки, обе обязательны:

rac infobase info --infobase=<uuid> ... | grep sessions-deny
curl -u <логин> http://127.0.0.1/<база>/hs/<корень>/status

Первая говорит, что база открыта по мнению кластера. Вторая — что она действительно отвечает. Ожидаем 200 или 401, но не 500.


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

/UpdateDBCfg отработала, ошибок нет. Но лежит ли в базе то, что вы правили?

Вопрос не праздный. Расширение могли параллельно менять с другой стороны — у нас, например, к базе имеет доступ подрядчик. Или ваш патч не доехал по какой-то из причин выше.

Надёжный способ — выгрузить расширение заново и сравнить с тем каталогом, который вы правили:

DESIGNER /DumpConfigToFiles /tmp/cfg_after -Extension <имя>
diff -r -x ConfigDumpInfo.xml /tmp/cfg_patched /tmp/cfg_after && echo ИДЕНТИЧНО

ConfigDumpInfo.xml исключать обязательно — там служебные версии выгрузки, они различаются всегда, и без -x вы будете вечно видеть расхождение.

Тот же приём работает и в обратную сторону: свежий дамп против дампа прошлой сессии показывает, менял ли расширение кто-то ещё, пока вас не было.


Мина седьмая: CRLF против LF

И вот здесь ждёт последняя засада. Вы делаете diff -rq двух дампов и получаете «файлы различаются» на весь файл целиком, хотя глазами разницы не видно.

Причина в переводах строк. 1С выгружает модули с CRLF. Если файл потом правился скриптом на Python, sed или любым другим инструментом с настройками по умолчанию, он превратится в LF. Содержательно файлы идентичны, побайтово — различаются в каждой строке.

Сравнивать надо с нормализацией:

diff <(tr -d '\r' < a.bsl) <(tr -d '\r' < b.bsl)

Для рекурсивного сравнения каталогов проще всего прогнать оба дерева через tr во временные копии, либо использовать diff --strip-trailing-cr.


Как выглядит цикл целиком

Собирая всё вместе, безопасный цикл правки боевого расширения получается такой:

  1. Снять дамп с боя/DumpConfigToFiles, это же ваш бэкап и точка отката.
  2. Сравнить с дампом прошлой сессии — убедиться, что расширение не меняли без вас.
  3. Внести правку в копию каталога, сохраняя CRLF.
  4. Залить в тестовую базу/LoadConfigFromFiles.
  5. Прогнать гейт/CheckModules -Server. Есть ошибки — цикл останавливается, в бой ничего не едет.
  6. Закрыть базу от пользователей, применить в бою: /LoadConfigFromFiles + /UpdateDBCfg.
  7. Открыть базу, проверить фактом: sessions-deny снят, HTTP-сервис отвечает.
  8. Снять дамп заново и сравнить с патченным каталогом — «идентично» означает, что в базе действительно ваш код.

Шаги 5, 7 и 8 — это те самые проверки, которых нет в наивном варианте и без которых автоматизация превращается в рулетку.

Реальный простой касс при таком цикле — около двух минут: столько занимает закрытие базы, применение и открытие обратно. Всё остальное делается на тестовой базе и кассиров не касается.


Что нельзя сделать из командной строки

Честности ради, пакетный режим закрывает не всё:

  • Внешнюю обработку с формой собрать из файлов не получится. /LoadExternalDataProcessorOrReportFromFiles падает с исключением XDTO при чтении Form.xml даже на нетронутом дампе, сделанном той же версией платформы. Обработки без формы собираются нормально.
  • Выполнить произвольный код через 1cv8 ENTERPRISE /Execute не выйдет — команда лишь открывает обработку, тело модуля объекта при этом не исполняется. Это тема отдельной статьи.
  • Интерактивная отладка остаётся за конфигуратором.

Выводы

Пакетный режим DESIGNER полностью закрывает цикл разработки расширений и позволяет держать 1С в нормальном CI рядом с остальным стеком. Но три вещи надо принять как данность:

  1. /CheckModules -Server — единственный настоящий гейт компиляции. Всё остальное молча пропустит битый код.
  2. Успешный код возврата ничего не гарантирует. Финальное состояние проверяется фактом: дамп плюс diff, sessions-deny плюс живой curl.
  3. Окружение важнее команд. Xvfb, setsid nohup, отсутствие модальных окон и честный pgrep — без этого цикл будет виснуть в местах, где вы не ожидаете.

Если выстроить это один раз, дальше правка боевого расширения занимает минуты и не требует ни RDP, ни присутствия в офисе, ни остановки торговли.


Платформа 8.3.27, УТ 11.5, сервер 1С на Linux. Все приёмы проверены на боевых базах розничной сети.

Вступайте в нашу телеграмм-группу Инфостарт

расширение DESIGNER пакетный режим CheckModules DevOps автоматизация Linux Xvfb УТ 11.5 командная строка CI

Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».

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

См. также

DevOps и автоматизация разработки Групповая разработка (Git, хранилище) Информационная безопасность Инструменты администратора БД Системный администратор Программист 1С 8.3 Беларусь Россия Казахстан Абонемент ($m)

Как реализовать безопасное маскирование данных в процессе CI/CD без создания промежуточных копий баз. Объясняем, как использовать инструмент pg_anon для автоматизации скрытия персональных данных при тестировании и развёртывании, сохраняя целостность и структуру информации. Материал объединяет практику Site Reliability Engineering (SRE) с задачами защиты данных, демонстрируя подход, при котором разработчики и DevOps;инженеры могут работать с реалистичными, но обезличенными данными, не нарушая требования безопасности и конфиденциальности.

1 стартмани

11.09.2026    479    Ninel_S    0    

0

DevOps и автоматизация разработки Администрирование СУБД Групповая разработка (Git, хранилище) Системный администратор Программист Руководитель проекта Стажер 1С 8.3 1С:Бухгалтерия государственного учреждения 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1C:ERP Беларусь Россия Казахстан Абонемент ($m)

В четвёртой части серии 1C:SRE-Suite мы переходим к практической автоматизации развёртывания отказоустойчивого кластера PostgreSQL для высоконагруженных систем 1С на Linux. В материале подробно разбирается инженерное решение без HAProxy — с использованием виртуального IP-адреса и vip-manager от CYBERTEC, обеспечивающего прямое подключение к активному мастеру без лишних задержек и точек отказа. Показана структура Ansible-модуля: подготовка ОС, развёртывание etcd, настройка Patroni с параметрами для больших нагрузок 1С. В конфигурационный шаблон Patroni автоматически закладываются параметры, критически важные для высоконагруженных баз данных, запуск vip-manager и полная автоматизация создания трёхнодового кластера. В конце — пошаговый Quick Start и планы развития модуля, включая резервное копирование, оптимизацию ОС Linux и rolling updates PostgreSQL.

1 стартмани

11.09.2026    384    Ninel_S    0    

0

DevOps и автоматизация разработки Программист 1С:Предприятие 8 1C:Бухгалтерия 1C:ERP 1С:УТ Бесплатно (free)

Я автоматизировал доставку доработок в базы 1С, к которым можно подключиться только по RDP через шлюз. У меня не было ни SSH, ни WinRM, ни общих папок, ни права устанавливать на сервер свои программы. Каналом связи стал диск рабочей станции, проброшенный в RDP-сеанс, а исполнителем команд служит PowerShell-агент в этом сеансе. В статье расскажу о захвате объектов и помещении изменений в хранилище, динамическом обновлении боевой базы с автоматической остановкой, установке расширений и доступе к базе через MCP по COM без клиента 1С. Ещё разберу несколько неочевидных ограничений платформы и RDP, с которыми столкнулся по ходу работы. Часть из них описана на форумах, а упоминаний о других я не нашёл.

10.09.2026    411    BiLBelarus    0    

1

DevOps и автоматизация разработки Администрирование СУБД Групповая разработка (Git, хранилище) Системный администратор Программист Руководитель проекта Стажер 1С 8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Управление холдингом 1С:Зарплата и Управление Персоналом 3.x 1С:Предприятие 8. Транспортная логистика, экспедирование и управление автотранспортом КОРП 1C:ERP Беларусь Россия Казахстан Абонемент ($m)

В корпоративных инсталляциях «1С:Предприятие 8.3» под управлением PostgreSQL всё чаще проявляются архитектурные пределы масштабирования: рост числа пользователей, обязательная маркировка, плотный поток API-интеграций и высокая стоимость простоя. Вводная часть цикла разбирает ключевые факторы современной эксплуатационной нагрузки и формирует инженерную методологию эволюционной модернизации без остановки продуктивного контура. Материал основан на практическом кейсе «Торговый контур» и показывает, как определить целевые метрики (p95, MTTR, APDEX), выстроить наблюдаемость, стабилизировать работу кластера и подготовить инфраструктуру к дальнейшему масштабированию. Публикация задаёт фундамент для последующих частей, посвящённых телеметрии, оптимизации PostgreSQL, CI/CD и архитектурному росту.

1 стартмани

10.09.2026    466    Ninel_S    0    

4

DevOps и автоматизация разработки Linux HighLoad оптимизация Групповая разработка (Git, хранилище) Системный администратор Программист Руководитель проекта 1С:Предприятие 8 1С 8.3 1С:Документооборот 1С:ERP Управление предприятием 2 1С:Управление холдингом 1С:Комплексная автоматизация 2.х Беларусь Россия Казахстан Абонемент ($m)

Системный анализ архитектурных границ масштабирования учетных систем «1С:Предприятие 8.3» под управлением PostgreSQL в ОС Linux. Формулирование инженерной методологии сквозного проекта «Торговый контур», определение измеримых целевых показателей (p95, MTTR, APDEX) и стратегии поэтапной модернизации эксплуатационного контура без остановки промышленных учетных процессов.

1 стартмани

07.09.2026    803    Ninel_S    9    

1

DevOps и автоматизация разработки Тестирование QA Групповая разработка (Git, хранилище) Программист 1С:Предприятие 8 Бесплатно (free)

Четыре года в интеграторе я работал с git и EDT. Git после хранилища полюбил сразу: видно, кто и что менял. С EDT сложнее: тормозит, ошибки при обновлении ERP, автономный сервер внутри него работает только с файловой базой. На новой работе команда захотела перейти на git, я развернул EDT, и оно на второй день разрушило проект при загрузке расширения. Тогда я решил дать команде git с привычным Конфигуратором и инструмент, который за минуту доносит коммит до базы через ibcmd, вместо получасовой загрузки из файлов. На новой работе разрешили ИИ, и я написал это приложение с его помощью: от чтения документации и первого ТЗ до идей в электричке. Впервые за годы снова почувствовал себя творцом, а не закрывателем задач. По дороге приросли выгрузка, объединение и проверка конфигурации по коммитам, YAxUnit и режим MCP-сервера. В статье: схемы, скриншоты, грабли и честный список ограничений. Ссылки пока нет: хочу понять, нужно ли это кому-то, кроме меня.

03.09.2026    10184    KatanaDragon511    28    

38

DevOps и автоматизация разработки Программист Бесплатно (free)

Представьте, что вас попросили «сделай нам DevOps для 1С». С чего начинать? Часто за этой потребностью скрывается хаос в самом процессе разработки. Поэтому начинать нужно не с инструментов, не с серверов и не со скриптов, а с понимания того, что именно необходимо изменить. Предлагаем небольшой спасительный чек-лист, по которому можно относительно безболезненно запустить современные процессы управления разработкой 1С, даже когда у команды нет ничего, а изменения они присылают друг другу почтой и в мессенджерах. Вы получите структурированный пошаговый список задач, с которым не страшно окунаться в любой проект аудита разработки на 1С с целью навести там порядок.

31.08.2026    2731    Evil Beaver    2    

13
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Ninel_S 27 25.08.26 00:17 Сейчас в теме
Коллега, Вы писали:
Пакетный режим DESIGNER полностью закрывает цикл разработки расширений и позволяет держать 1С в нормальном CI рядом с остальным стеком. Но три вещи надо принять как данность:

/CheckModules -Server — единственный настоящий гейт компиляции. Всё остальное молча пропустит битый код.
Успешный код возврата ничего не гарантирует. Финальное состояние проверяется фактом: дамп плюс diff, sessions-deny плюс живой curl.
Окружение важнее команд. Xvfb, setsid nohup, отсутствие модальных окон и честный pgrep — без этого цикл будет виснуть в местах, где вы не ожидаете.
Если выстроить это один раз, дальше правка боевого расширения занимает минуты и не требует ни RDP, ни присутствия в офисе, ни остановки торговли.


Разрешите дополнить Вашу статью примером практического скрипта, который парсит скрытые ошибки. Скрипт исправляет главную «неприятность» пакетного режима — обход ложного кода возврата 0. Он принудительно анализирует сгенерированный файл отчета Конфигуратора с помощью регистронезависимого поиска (grep -qi) ключевых слов ошибок синтаксиса. Если в коде расширения есть «битые» методы, скрипт вернет системный статус 1 и остановит пайплайн, даже если сама платформа 1С отрапортовала об успешном закрытии. Скрипт полностью параметризован (поддерживает ключи для строки подключения СУБД/файловой базы, имени расширения, авторизации и кастомных таймаутов). Его можно встроить в .gitlab-ci.yml или GitHub Actions одной строкой.
Прикрепленные файлы:
1c-ci-linux-build.sh
2. YA_2159986692 28 25.08.26 01:59 Сейчас в теме
(1) Спасибо, это ровно то дополнение, которого статье не хватало. Проблему вы назвали точно: платформа рапортует об успехе, а пайплайн едет дальше с битым кодом.

Сразу оговорюсь: ваш скрипт я пока не открывал, отвечаю по описанию подхода. Разбор отчёта грепом — вещь рабочая, и у меня похожая проверка стоит. Добавлю четыре грабли, на которые такой парсер натыкается, чтобы коллеги не поймали ложный «успех»:

1. Кодировка файла отчёта. Если /Out окажется не в UTF-8, grep не найдёт ничего и вернёт ноль — то есть «ошибок нет». Это худший из отказов: тихий и в пользу «всё хорошо». Стоит либо прогонять файл через iconv, либо явно проверять, что он читается.

2. Пустой или несозданный отчёт. Отсутствие файла и нулевой размер — это не «успех», это «команда не отработала». Проверять существование и ненулевую длину отдельно, до всякого грепа.

3. Локализация ключевых слов. «Неопознанный оператор» есть только на русской платформе. На англоязычной установке список слов надо другой, иначе парсер снова промолчит.

4. Один файл на несколько шагов. Если /Out переиспользуется, старые сообщения дают либо ложное срабатывание, либо, при перезаписи, потерю ошибок предыдущего шага. Лучше свой файл на каждую команду.

И ещё: разбор отчёта дополняет /CheckModules, но не заменяет его. Гейт даёт модуль, строку и колонку — по этому можно сразу чинить. Грепом вы узнаете только факт.

От себя добавлю пятый слой, который ловит то, что не ловит ни то ни другое: сверка результата фактом. После UpdateDBCfg выгрузить расширение заново и сравнить с патченным каталогом через diff -r -x ConfigDumpInfo.xml. Служебный файл с версиями выгрузки исключать обязательно, он отличается всегда. И сверять с нормализацией переводов строк: платформа пишет CRLF, а скрипт мог оставить LF, и вы получите «различаются» на содержательно одинаковых файлах.

Коллегам, кто будет брать скрипт: прочитайте его перед запуском, он ходит в боевую базу.
pavlov_dv; +1 Ответить
3. Ninel_S 27 25.08.26 13:10 Сейчас в теме
(2)
Коллегам, кто будет брать скрипт: прочитайте его перед запуском, он ходит в боевую базу

Коллеги, скрипт будет "ходить" туда, куда Вы его пошлете. Тестировать полученные извне скрипты на боевой базе - так себе практика.
Уважаемый Автор, я изучила Ваши "отборные грабли" и доработала скрипт, который прикрепила к этому посту. Вот его идеология, созданная по мотивам Ваших идей:
Пять слоев защиты 1C-CI от ложного «успеха» (False Success)
Слой 1. Динамическая нормализация кодировок и удаление BOM
Проблема: Платформа 1С в зависимости от ОС сервера и настроек может писать лог /Out в кодировках UTF-16LE, CP1251 или UTF-8. Обычный Linux-инструментарий (grep, awk) в стандартном UTF-8 окружении не сможет прочесть текст в другой кодировке. Поиск ошибок вернет нулевой код (ошибок нет), замаскировав критический сбой.
Решение: Скрипт определяет кодировку лога утилитой file --mime-encoding. Если кодировка отличается от UTF-8, файл принудительно конвертируется через iconv -f <кодировка> -t UTF-8. Дополнительно с помощью sed вырезается невидимый BOM-символ (\xEF\xBB\xBF), который часто ломает регулярные выражения на первой строке лога.
Слой 2. Жесткая валидация физического наличия и размера лога
Проблема: Если Конфигуратор аварийно упал на самом старте (сбой СУБД, проблемы с лицензированием, отсутствие прав доступа), файл лога либо вообще не создается, либо создается пустым. Поиск ключевых слов ошибок в пустом файле всегда возвращает «успех», и битый пайплайн завершается зеленой галочкой.
Решение: До запуска регулярных выражений в скрипте выполняется проверка существования и ненулевого размера файла лога ([[ -s "$LOG_FILE" ]]). Если условие не выполнено — сборка немедленно падает, а скрипт выводит в консоль содержимое потока stderr, перехваченное при запуске процесса 1cv8.
Слой 3. Мультиязычный POSIX-шаблон регулярных выражений
Проблема: Текст ошибок компиляции жестко завязан на локализацию платформы 1С. Поиск только по русскому слову «Ошибка» гарантированно пропустит критические сообщения вида Error, Expected или Undefined на серверах с англоязычной локалью ОС или платформы.
Решение: Отказ от простых проверок на наличие слова "ошибка". Поиск ведется по расширенному регулярному шаблону, объединяющему маркеры компилятора на обоих языках: "ошибка|неопознан|ожидается|не определен|несоответств|не найден|неверн|error|expected|undefined|mismatch|not found|invalid|failed"
Слой 4. Изоляция сессий сборки (Уникальный RUN_ID)
Проблема: При параллельном запуске нескольких сборок на одном GitLab/GitHub-раннере или последовательных шагах без глубокой очистки окружения, процессы могут читать «грязные» логи предыдущих запусков. Это приводит либо к ложным срабатываниям, либо к игнорированию свежих ошибок из-за перезаписи файлов.
Решение: Каждая сессия генерирует случайный идентификатор RUN_ID на основе даты и времени. Файлы отчетов и системных ошибок создаются в каталоге /tmp/ с уникальными именами (например, /tmp/1c_log_${RUN_ID}.txt). Встроенный обработчик trap cleanup EXIT гарантирует безусловное удаление этих временных файлов при любом исходе сборки.
Слой 5. Верификация результатом (Идемпотентный diff-контроль)
Проблема: Синтаксический контроль /CheckModules проверяет только корректность написания кода. Он не гарантирует, что конфигурация СУБД применилась на 100% идентично коммиту в Git, и не защищает от ситуации, когда в базу были внесены ручные правки в обход репозитория.
Решение: После выполнения команды /UpdateDBCfg скрипт вызывает /DumpConfigToFiles во временный каталог и сверяет выгруженную конфигурацию с исходным каталогом Git с помощью diff -r. При сверке используются ключ --strip-trailing-cr (для игнорирования различий в переводах строк CRLF от 1С и LF в Git) и ключ исключения -x "ConfigDumpInfo.xml" (служебный файл версий платформы, который уникален при каждой выгрузке). Расхождение на одну строку прерывает пайплайн.
Прикрепленные файлы:
1c-ci-linux-build-v2.sh
4. kuzyara 2265 26.08.26 11:23 Сейчас в теме
получить список открытых модальных окон 1c в xvfb можно с помощью python библиотеки Xlib
def read_window_titles():
    if sys.platform != "linux":
        return
    # Let's try to find a window "Проверка правомерности использования конфигурации"
    import Xlib.display
    try:
        disp = Xlib.display.Display()
        root = disp.screen().root
        window_ids = root.query_tree().children
    except Xlib.error.DisplayConnectionError as err:
        print(f"Error processing Xlib displays: {err}")
        return
    except Exception as err:
        # Generic error handling
        print(f"Error processing Xlib: {err}")
        return
    list_titles = []
    for window_id in window_ids:
        try:
            window_obj = disp.create_resource_object('window', window_id)
            net_wm_name = disp.intern_atom('_NET_WM_NAME')
            title_property = window_obj.get_full_property(net_wm_name, 0)
            title = title_property.value.decode('utf-8').strip() if title_property else ""
        except Xlib.error.XError:
            # Handle cases where    a window might have been closed or is invalid
            continue
        except Exception as err:
            # Generic error handling
            print(f"Error processing window {window_id}: {err}")
            continue
        list_titles.append(title)
    window_titles = set([x for x in list_titles if x])
    logger.debug(f"window_titles: {window_titles}")
    out_files = os.environ.get("OUT_FILES")
    if out_files:
        os.makedirs(out_files, exist_ok=True)
        titles_path = os.path.join(out_files, "window_titles.txt")
        logger.debug(f"titles_path: {titles_path}")
        with open(titles_path, 'w', encoding='utf-8-sig') as log_file:
            log_file.write(str(window_titles))
Показать
5. kuzyara 2265 26.08.26 11:44 Сейчас в теме
Мина седьмая: CRLF против LF
Чтобы в репе не было crlf необходимо включать автоматическую конвертацию core.autocrlf=true
https://stackoverflow.com/questions/1967370/git-replacing-lf-with-crlf

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

Хоть я и не увидел упоминания git в статье
6. grumagargler 759 26.08.26 16:20 Сейчас в теме
> Мина первая: загрузка не значит компиляция

Я бы очень сильно удивился, если бы /LoadConfigFromFiles компилировал модули и не позволял загружать в конфигурацию файлы, которые были от-туда выгружены.
7. Ruslic 7 27.08.26 16:27 Сейчас в теме
Моя ИИ прочитала и вот что написала:

"А в двух местах статья расходится с нашим опытом, и это интереснее всего:

- Автор пишет, что внешнюю обработку с формой из файлов собрать не получится — падает XDTO на Form.xml. У нас это работает: цепочка epf-init + form-compile + LoadExternal собирает .epf с формой, на этом стоит целый навык.
- Он же утверждает, что 1cv8 ENTERPRISE /Execute не исполняет модуль объекта. Наш 1c-exec устроен именно так и код выполняет — я сегодня гонял через него проверки арифметики ПДн и запросы к базе."
Для отправки сообщения требуется регистрация/авторизация