CI/CD для 1С с нуля: велосипед для деплоя EDT-проекта

27.02.26

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

Входные данные - конфигурация 1С в формате EDT, для системы контроля версий используется Git, две базы - рабочая и тестовая. Задача: коммит в ветку должен автоматически обновлять базу. Без ручного запуска конфигуратора, без «сохрани CF и скопируй на сервер». Инструмент - GitHub Actions + PowerShell-скрипты на сервере. Платформа 8.3.27.

Архитектура

Две ветки — две базы:

  • ветка develop  →  база ProdBase  (рабочая, продуктивная)
  • ветка test     →  база TestBase  (тестовая)

 

Два режима деплоя:

  • Hot deploy — динамическое обновление без остановки сеансов. Только для изменений BSL-кода.
  • Full deploy — полное обновление с завершением сеансов. Для изменений метаданных.

 

Логика срабатывания:

Коммит в develop:

  → только BSL?   →  hot deploy ProdBase  →  auto-merge test  →  hot deploy TestBase

  → метаданные?   →  schedule 8:00 ProdBase  →  auto-merge test  →  full deploy TestBase

 

Коммит в test:

  →  hot или full deploy TestBase

  →  НЕТ автомержа в develop (только вручную)

 

Каждый день в 8:00:

  →  full deploy ProdBase из develop

 

 

Окружение и переменные

Все секреты хранятся в GitHub Actions Secrets и передаются в скрипт через переменные окружения. Ни один пароль не записан в файлах репозитория.

 

Переменные GitHub Actions Secrets

ADMIN_USER     = deploy_svc          # учётная запись администратора ИБ

ADMIN_PASSWORD = ***                  # пароль (хранится зашифрованным в GitHub)

 

Параметры сервера

# Адрес 1С-сервера (Windows Server с компонентами 1С)

$ServerHost = "1c-app-01"

 

# Имя кластера (задаётся при установке сервера 1С)

$Cluster    = "MAIN-CLUSTER"

 

# Имена информационных баз в кластере

$ProdBase   = "ProdBase"

$TestBase   = "TestBase"

 

# Адрес RAS-сервиса (порт 1545 по умолчанию)

$RasAddress = "1c-app-01:1545"

 

Строки подключения к ИБ

Строка подключения к серверной ИБ состоит из имени сервера (Srvr) и имени базы в кластере (Ref). Кавычки внутри строки экранируются при передаче через командную строку.

# Рабочая база

Srvr="1c-app-01";Ref="ProdBase";

 

# Тестовая база

Srvr="1c-app-01";Ref="TestBase";

 

Пути к исполняемым файлам

# Платформа 1С (автоопределяется по последней версии в папке)

$PlatformExe = "C:\Program Files\1cv8\8.3.27.1989\bin\1cv8.exe"

$RacExe      = "C:\Program Files\1cv8\8.3.27.1989\bin\rac.exe"

 

# 1C:EDT CLI (версия фиксируется при установке EDT на CI-агенте)

$EdtCli = "C:\Program Files\1C\1CE\components\

          1c-edt-2025.1.4+15-x86_64\1cedtcli.exe"

 

# Путь к EDT-проекту (рабочая копия репозитория)

$ProjectPath = "D:\CI\workspace\MyProject"

Проблема 1: EDT и LoadConfigFromFiles

EDT-формат (.mdo-файлы) платформа не понимает напрямую. Команда /LoadConfigFromFiles ожидает XML-формат конфигуратора. Нужна конвертация.

 

Первый подход — через временную базу

Логика выглядела разумно: создать временную файловую базу, загрузить туда EDT через LoadConfigFromFiles, экспортировать XML через DumpConfigToFiles.

CREATEINFOBASE  →  LoadConfigFromFiles (EDT)  →  UpdateDBCfg

→  DumpConfigToFiles  →  XML  →  LoadConfigFromFiles (целевая БД)

Изменения метаданных применялись корректно. BSL-код — нет. LoadConfigFromFiles для существующей базы загружает структуру метаданных, но модули существующих объектов не обновляет. DumpConfigToFiles экспортирует то, что загрузилось — XML без актуального BSL.

 

Решение — 1cedtcli напрямую

1cedtcli умеет экспортировать EDT-проект напрямую в XML-формат конфигуратора, минуя промежуточную базу. Полная строка вызова:

"C:\Program Files\1C\1CE\components\1c-edt-2025.1.4+15-x86_64\1cedtcli.exe" ^

  -data "D:\CI\workspace\edt-ws-20250115-103000" ^

  -command export ^

  --project "D:\CI\workspace\MyProject" ^

  --configuration-files "D:\CI\workspace\xml-20250115-103000" ^

  -nl ru_RU

Параметры:

  • -data — временная рабочая папка EDT (создаётся скриптом, удаляется после)
  • --project — путь к EDT-проекту (папка с файлом .project)
  • --configuration-files — куда положить XML (папка с Configuration.xml)
  • -nl ru_RU — локаль для сообщений

 

Этот XML содержит актуальный BSL из EDT-проекта. После этого стандартная цепочка:

# Шаг 1: загрузка XML в конфигурацию базы

"C:\Program Files\1cv8\8.3.27.1989\bin\1cv8.exe" DESIGNER ^

  /DisableStartupDialogs ^

  /IBConnectionString "Srvr=""1c-app-01"";Ref=""ProdBase"";" ^

  /N "deploy_svc" ^

  /P "***" ^

  /LoadConfigFromFiles "D:\CI\workspace\xml-20250115-103000" ^

  /Out "D:\CI\logs\deploy-hot-ProdBase-20250115-103000.log"

 

# Шаг 2: динамическое обновление без остановки сеансов

"C:\Program Files\1cv8\8.3.27.1989\bin\1cv8.exe" DESIGNER ^

  /DisableStartupDialogs ^

  /IBConnectionString "Srvr=""1c-app-01"";Ref=""ProdBase"";" ^

  /N "deploy_svc" ^

  /P "***" ^

  /UpdateDBCfg -Dynamic+ ^

  /Out "D:\CI\logs\deploy-hot-ProdBase-20250115-103000.log"

 

О рисках динамического обновления

Динамическое обновление (-Dynamic+) не требует перезапуска сеансов, но у него есть обратная сторона: в момент применения изменений активные пользователи продолжают работать с предыдущей версией кода. Если модуль был изменён, а пользователь не перезашёл — он работает со «старым» кодом до конца сеанса. В редких случаях это может привести к временной несогласованности.

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

Если после динамического обновления что-то пошло не так и база не отвечает штатно, вопрос решается двумя SQL-запросами к базе данных — сброс флагов dbschema и config приводит базу к исходному состоянию без динамики. Это занимает минуты.

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

 

Проблема 2: дедлок при управлении сеансами

Full deploy требует завершить активные сеансы перед обновлением. Первое очевидное решение — вызвать для этого HTTP-сервис, который уже был в конфигурации.

 

Что такое HTTP-сервис 1С

В конфигурации был написан стандартный HTTP-сервис (объект метаданных «HTTP-сервисы»). Он публиковался на веб-сервере IIS под URL вида:

http://1c-app-01/MyApp/hs/admin/

Сервис принимал команды от CI-скрипта через REST-запросы:

POST /hs/admin/block     → запустить фоновое задание «заблокировать сеансы»

POST /hs/admin/terminate → запустить фоновое задание «завершить сеансы»

POST /hs/admin/unblock   → запустить фоновое задание «снять блокировку»

GET  /hs/admin/status/{id} → проверить статус задания

Логика: скрипт отправлял команду, получал ID задания, опрашивал /status пока не получал «выполнено». Так сделано, потому что BSL-код на сервере 1С не может выполниться мгновенно в рамках HTTP-запроса — нужен фоновый процесс.

 

Почему это не работает для блокировки

На практике всё вставало намертво. HTTP-сервис и фоновые задания живут в одном рабочем процессе rphost.exe.

Сценарий дедлока:

  • 1. Скрипт вызывает POST /block — HTTP-запрос доходит до рабочего процесса, BSL-код запускает ФЗ «заблокировать сеансы».
  • 2. Фоновое задание отрабатывает: ЗапретНачалаСеансов = Истина. Планировщик заданий останавливается.
  • 3. Скрипт опрашивает /status — запрос тоже обрабатывается рабочим процессом, это работает.
  • 4. Скрипт делает деплой, затем вызывает POST /unblock.
  • 5. HTTP-запрос /unblock доходит до рабочего процесса. Код пытается создать фоновое задание «снять блокировку».
  • 6. Планировщик заданий остановлен. Фоновое задание не запускается. Ответ не возвращается. База остаётся заблокированной навсегда.

 

 

Решение — rac.exe через RAS

rac.exe — утилита администрирования кластера серверов 1С. Она обращается к сервису RAS (Remote Administration Service) по порту 1545. RAS — это отдельный процесс 1CEnterprise83RAS.exe, полностью независимый от рабочих процессов баз данных.

Блокировка базы через rac.exe выполняется на уровне кластера, а не на прикладном уровне ИБ. Даже если база мёртвая — rac.exe всё равно пройдёт.

 

Полные строки вызова:

# Шаг 1: получить ID кластера

"C:\Program Files\1cv8\8.3.27.1989\bin\rac.exe" 1c-app-01:1545 cluster list

# → выводит: cluster : xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

# → name    : MAIN-CLUSTER

 

# Шаг 2: найти UUID информационной базы по имени

"C:\Program Files\1cv8\8.3.27.1989\bin\rac.exe" 1c-app-01:1545 ^

  infobase summary list ^

  --cluster=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

# → выводит список баз, ищем name=ProdBase, берём infobase : uuid

 

# Шаг 3: заблокировать начало новых сеансов

"C:\Program Files\1cv8\8.3.27.1989\bin\rac.exe" 1c-app-01:1545 ^

  infobase update ^

  --cluster=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx ^

  --infobase=yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy ^

  --infobase-user=deploy_svc ^

  --infobase-pwd=*** ^

  --sessions-deny=on ^

  --denied-message="Database update in progress. Start after 8:30." ^

  --permission-code=CI_CD_Deploy

 

# Шаг 4: завершить конкретный активный сеанс

"C:\Program Files\1cv8\8.3.27.1989\bin\rac.exe" 1c-app-01:1545 ^

  session terminate ^

  --cluster=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx ^

  --session=zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz

 

# Шаг 5: после деплоя — разблокировать

"C:\Program Files\1cv8\8.3.27.1989\bin\rac.exe" 1c-app-01:1545 ^

  infobase update ^

  --cluster=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx ^

  --infobase=yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy ^

  --infobase-user=deploy_svc ^

  --infobase-pwd=*** ^

  --sessions-deny=off

 

Параметр --permission-code=CI_CD_Deploy задаёт код разрешения. Скрипт, который запускает Designer для деплоя, передаёт этот же код в строке подключения — тогда конфигуратор подключается даже при активной блокировке:

# Строка подключения с кодом разрешения для сеансов-исключений

Srvr="1c-app-01";Ref="ProdBase";Pwd="CI_CD_Deploy";

Предварительное условие: на сервере должен быть запущен RAS-сервис. Проверить и запустить:

# Проверить статус RAS

Get-Service -Name "1CEnterprise83RAS"

 

# Запустить, если остановлен

Start-Service -Name "1CEnterprise83RAS"

 

# Настроить автозапуск

Set-Service -Name "1CEnterprise83RAS" -StartupType Automatic

 

Что стоит запомнить

  • LoadConfigFromFiles с временной базой не обновляет BSL существующих объектов. Используй 1cedtcli export --configuration-files напрямую из EDT-проекта.
  • HTTP-сервис базы и rac.exe — принципиально разные инструменты. Первый зависит от работоспособности базы, второй нет. Для управления сеансами при деплое нужен второй.
  • RAS на сервере — обязательное условие для rac.exe. Установи и настрой автозапуск заранее, а не в момент дедлока.
  • Параметр --permission-code позволяет CI-скрипту подключиться к заблокированной базе для деплоя, не снимая блокировку раньше времени.
  • Разделение деплоев на hot (BSL) и full (метаданные) позволяет рабочим базам получать исправления сразу, без ночного окна.

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

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

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

См. также

Инструментарий разработчика Нейросети DevOps и автоматизация разработки Тестирование QA Разработчик 1С 8.3 Бесплатно (free)

Открытый набор правил и скриптов на GitHub для ИИ-агента (агента искусственного интеллекта: Claude Code, Codex и других). Агент сам снимает опись машины, предлагает путь проверки кода: плагин Unica или BSL Language Server со справкой платформы. С вашего «да» ставит недостающее, затем выгружает внешнюю обработку, заводит git и доводит её до зелёного теста YAxUnit. Оба пути проверены с нуля свежим агентом на копии демобазы «Управление торговлей» 11.5, платформа 8.3.27. Новая часть: для задач по данным базы агент выгружает конфигурацию в XML, строит карту объектов и пишет запросы только по именам, найденным в выгрузке. Внутри гайд «Unica на Windows» с известными ошибками и проверенными обходами.

вчера в 14:30    170    Iliaelagin    0    

1

DevOps и автоматизация разработки Групповая разработка (Git, хранилище) Системный администратор Разработчик 1С 8.3 1С 8.5 Бесплатно (free)

В прошлой статье у ERP оставалось 89 отказов загрузки, у ЗУП — 19. Теперь обе конфигурации совпали с эталонами, а собранные файлы прошли круг через платформу. Развертка выделена в открытый репозиторий cf-unwrapper: библиотека на Rust и консольная утилита. Показываю результаты, объясняю границы «100%» и приглашаю к проверкам и развитию проекта.

02.11.2026    282    oyti    1    

1

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

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

02.11.2026    553    vanya_gonchar    2    

6

Файловый обмен (TXT, XML, DBF), FTP DevOps и автоматизация разработки Групповая разработка (Git, хранилище) Системный администратор Разработчик 1С 8.5 Бесплатно (free)

В прошлой статье я выгрузил Бухгалтерию в XML байт в байт и спросил, на чем проверить дальше. Вы ответили: ERP, старые релизы, зарплата. Прогнал пять конфигураций, от клиента ЭДО до ERP на 120 тысяч файлов. Рассказываю, что сломалось после Бухгалтерии, почему эталону платформы нельзя верить на слово, как выгрузить одну конфигурацию в формат трех версий платформы - и почему cf-конвертер становится отдельным продуктом, Разверткой.

02.11.2026    371    oyti    2    

3

Инструментарий разработчика DevOps и автоматизация разработки Разработчик 1С 8.3 Абонемент ($m)

Как отличить срочное исправление от обычного вечернего коммита? Проверила расчёт показателей поставок по отчёту хранилища 1С и истории двух открытых проектов. На стенде счётчики совпали со сценарием, а в выборке открытого проекта правило «те же объекты» ошиблось во всех шести случаях. Показываю границы такого замера и отличие от метрик DORA. Прилагаются инструмент и материалы опыта.

1 стартмани

29.10.2026    349    Ninel_S    0    

0

DevOps и автоматизация разработки Групповая разработка (Git, хранилище) Файловый обмен (TXT, XML, DBF), FTP Системный администратор Разработчик 1С 8.5 Бесплатно (free)

Выгрузка типовой Бухгалтерии в XML через базу занимает больше четырёх минут. Я написал движок, который читает файл конфигурации напрямую и выгружает его за 35 секунд, совпадая с выгрузкой платформы байт в байт во всех 90 385 файлах. Загрузка обратно тоже работает: круг через платформу совпадает полностью. Рассказываю, как ускоряли, как проверяем и что при загрузке XML теряет сама платформа. А в конце спрашиваю, нужно ли это кому-то, кроме меня, и на какой конфигурации проверить следующей.

27.10.2026    928    oyti    20    

16

DevOps и автоматизация разработки Групповая разработка (Git, хранилище) Разработчик 1С 8.3 Абонемент ($m)

Хук pre-commit проверяет полный снимок индекса Git в отдельной базе 1С. На «Нано-УТ» и платформе 8.3.27 повторила 12 попыток коммита: восемь прошли, четыре остановлены. Чистый коммит занял 31,8 с. Вызов несуществующего метода общего модуля хук останавливает только с ключом -ExtendedModulesCheck. В архиве версия 2, тесты, инструкция и журналы.

1 стартмани

26.10.2026    374    Ninel_S    2    

-1

Нейросети DevOps и автоматизация разработки Разработчик 1С 8.3 Абонемент ($m)

Я дала агенту Claude Code задачу словами: добавить в учебную конфигурацию документ «Внутреннее потребление товаров», который списывает товар по средней стоимости и не даёт уйти в минус. Три запуска с нуля, каждый принят проверкой на платформе 1С: 1 мин 49 с, 2 мин 33 с и 2 мин 56 с. Показываю, что агент поменял, где ошибался и почему на типовой УТ так быстро не будет.

1 стартмани

26.10.2026    660    Ninel_S    0    

-1
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. пользователь 14.05.26 09:03
Пара вопросов:
1. Разве 1scli не может обновить базу?
2. Зачем статью "Как мы пытались сделать обновление 1с" называть ci/cd если по факту не описана автоматизация обновления?
3. Где запуск после заливки конфига для отработки обработчиков обновления?

История с веб сервисом повеселила конечно)
2. OneCBel 14 14.05.26 13:05 Сейчас в теме
(1)
1. Если Вы имели в виду 1cedtcli - он умеет только экспортировать EDT-проект в XML конфигуратора.
2. От пуша до боевой базы без ручных шагов немного относится к автоматизации, как мне кажется.
3. Не у всех конфигурации на БСП, мир немного шире типовых.
3. NeTan-root 13.06.26 06:51 Сейчас в теме
А знает кто как бы организовать инкрементальное обновление конфигурации в файлы xml? Поясню: Есть у меня ERP, я не хочу из EDT выгружать в cf или xml всю конфу с нуля(это занимает ~час). Я хочу чтобы EDT уже существующую выгрузку xml просто обновил, т.е обновил только изменённые файлы. Конфигуратор так умеет(умеет загрузить дельту xml и выгрузить дельту xml), а вот edt так делает только с подключенной базой. Обновлять подключенную базу, а затем через конфигуратор выгружать дельту слишком муторно. Хочется простую команду в edtcli...
Для отправки сообщения требуется регистрация/авторизация